diff --git a/404.html b/404.html index e151b1bdd..8d9f6bf0d 100644 --- a/404.html +++ b/404.html @@ -10,13 +10,13 @@ - - + +
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/js/042c512d.e493c2d8.js b/assets/js/042c512d.a6805c54.js similarity index 98% rename from assets/js/042c512d.e493c2d8.js rename to assets/js/042c512d.a6805c54.js index 944bf80a6..9d31f383e 100644 --- a/assets/js/042c512d.e493c2d8.js +++ b/assets/js/042c512d.a6805c54.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2018],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var i=r(7294);function l(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function a(e){for(var t=1;t=0||(l[r]=e[r]);return l}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var o=i.createContext({}),u=function(e){var t=i.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=u(e.components);return i.createElement(o.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var r=e.components,l=e.mdxType,n=e.originalType,o=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=u(r),d=l,b=m["".concat(o,".").concat(d)]||m[d]||p[d]||n;return r?i.createElement(b,a(a({ref:t},c),{},{components:r})):i.createElement(b,a({ref:t},c))}));function d(e,t){var r=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var n=r.length,a=new Array(n);a[0]=m;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s.mdxType="string"==typeof e?e:l,a[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>p,frontMatter:()=>n,metadata:()=>s,toc:()=>u});var i=r(7462),l=(r(7294),r(3905));const n={slug:"multi-cluster",title:"Multi-cluster observability",sidebar_label:"Multi-cluster observability"},a=void 0,s={unversionedId:"use-cases/multi-cluster",id:"use-cases/multi-cluster",title:"Multi-cluster observability",description:"Introduction",source:"@site/product/use-cases/multi-cluster.md",sourceDirName:"use-cases",slug:"/use-cases/multi-cluster",permalink:"/product/use-cases/multi-cluster",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/multi-cluster.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"multi-cluster",title:"Multi-cluster observability",sidebar_label:"Multi-cluster observability"}},o={},u=[{value:"Introduction",id:"introduction",level:2},{value:"Multi-cluster observability with Otomi",id:"multi-cluster-observability-with-otomi",level:2}],c={toc:u};function p(e){let{components:t,...n}=e;return(0,l.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h2",{id:"introduction"},"Introduction"),(0,l.kt)("p",null,"Using multiple Kubernetes clusters can have advantages based on your requirements. Some of the benefits of running multiple Kubernetes clusters are:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"High availability: When one cluster fails, the other cluster(s) can take the load. Losing one cluster when your applications are appropriately spread across several other clusters is much better than losing a single cluster with everything on it"),(0,l.kt)("li",{parentName:"ul"},"Better end user experience: Splitting workloads can improve performance and reduce latency by providing users with a geographically close environment"),(0,l.kt)("li",{parentName:"ul"},"Separate development and production clusters to reduce the risk of being served beta or non-production code versions")),(0,l.kt)("p",null,"But from a technical perspective, managing multiple Kubernetes clusters is more complex than managing a single cluster. For effective multi-cluster management, a \u201csingle pane of glass\u201d with centralized real-time monitoring, time series comparisons across and within clusters and high availability is essential for teams operating with multiple clusters and multiple providers."),(0,l.kt)("h2",{id:"multi-cluster-observability-with-otomi"},"Multi-cluster observability with Otomi"),(0,l.kt)("p",null,"The following image shows a multi-cluster observability setup using Otomi:"),(0,l.kt)("p",null,(0,l.kt)("img",{alt:"multi-cluster",src:r(1195).Z,width:"1556",height:"1226"})),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Aggregation of metrics from workload clusters for Prometheus high availability and single pane of glass"),(0,l.kt)("li",{parentName:"ol"},"Multi-cluster log aggregation"),(0,l.kt)("li",{parentName:"ol"},"Preconfigured multi-cluster dashboards"),(0,l.kt)("li",{parentName:"ol"},"Multi-cluster alerting")),(0,l.kt)("p",null,"This multi-cluster setup can be expanded with:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Running Harbor on the management cluster to provide image and chart registries for the workload clusters"),(0,l.kt)("li",{parentName:"ul"},"Replicate workload cluster Git repositories to the management cluster Git repository"),(0,l.kt)("li",{parentName:"ul"},"Deploy multiple application clusters based on a single cluster profile")))}p.isMDXComponent=!0},1195:(e,t,r)=>{r.d(t,{Z:()=>i});const i=r.p+"assets/images/multi-cluster-dd1d21f51c8f0d0623e575b53e84568d.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2018],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var i=r(7294);function l(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function a(e){for(var t=1;t=0||(l[r]=e[r]);return l}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var o=i.createContext({}),u=function(e){var t=i.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=u(e.components);return i.createElement(o.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var r=e.components,l=e.mdxType,n=e.originalType,o=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=u(r),d=l,b=m["".concat(o,".").concat(d)]||m[d]||p[d]||n;return r?i.createElement(b,a(a({ref:t},c),{},{components:r})):i.createElement(b,a({ref:t},c))}));function d(e,t){var r=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var n=r.length,a=new Array(n);a[0]=m;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s.mdxType="string"==typeof e?e:l,a[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>p,frontMatter:()=>n,metadata:()=>s,toc:()=>u});var i=r(7462),l=(r(7294),r(3905));const n={slug:"multi-cluster",title:"Multi-cluster observability",sidebar_label:"Multi-cluster observability"},a=void 0,s={unversionedId:"use-cases/multi-cluster",id:"use-cases/multi-cluster",title:"Multi-cluster observability",description:"Introduction",source:"@site/product/use-cases/multi-cluster.md",sourceDirName:"use-cases",slug:"/use-cases/multi-cluster",permalink:"/product/use-cases/multi-cluster",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/multi-cluster.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"multi-cluster",title:"Multi-cluster observability",sidebar_label:"Multi-cluster observability"}},o={},u=[{value:"Introduction",id:"introduction",level:2},{value:"Multi-cluster observability with Otomi",id:"multi-cluster-observability-with-otomi",level:2}],c={toc:u};function p(e){let{components:t,...n}=e;return(0,l.kt)("wrapper",(0,i.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h2",{id:"introduction"},"Introduction"),(0,l.kt)("p",null,"Using multiple Kubernetes clusters can have advantages based on your requirements. Some of the benefits of running multiple Kubernetes clusters are:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"High availability: When one cluster fails, the other cluster(s) can take the load. Losing one cluster when your applications are appropriately spread across several other clusters is much better than losing a single cluster with everything on it"),(0,l.kt)("li",{parentName:"ul"},"Better end user experience: Splitting workloads can improve performance and reduce latency by providing users with a geographically close environment"),(0,l.kt)("li",{parentName:"ul"},"Separate development and production clusters to reduce the risk of being served beta or non-production code versions")),(0,l.kt)("p",null,"But from a technical perspective, managing multiple Kubernetes clusters is more complex than managing a single cluster. For effective multi-cluster management, a \u201csingle pane of glass\u201d with centralized real-time monitoring, time series comparisons across and within clusters and high availability is essential for teams operating with multiple clusters and multiple providers."),(0,l.kt)("h2",{id:"multi-cluster-observability-with-otomi"},"Multi-cluster observability with Otomi"),(0,l.kt)("p",null,"The following image shows a multi-cluster observability setup using Otomi:"),(0,l.kt)("p",null,(0,l.kt)("img",{alt:"multi-cluster",src:r(1195).Z,width:"1556",height:"1226"})),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Aggregation of metrics from workload clusters for Prometheus high availability and single pane of glass"),(0,l.kt)("li",{parentName:"ol"},"Multi-cluster log aggregation"),(0,l.kt)("li",{parentName:"ol"},"Preconfigured multi-cluster dashboards"),(0,l.kt)("li",{parentName:"ol"},"Multi-cluster alerting")),(0,l.kt)("p",null,"This multi-cluster setup can be expanded with:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Running Harbor on the management cluster to provide image and chart registries for the workload clusters"),(0,l.kt)("li",{parentName:"ul"},"Replicate workload cluster Git repositories to the management cluster Git repository"),(0,l.kt)("li",{parentName:"ul"},"Deploy multiple application clusters based on a single cluster profile")))}p.isMDXComponent=!0},1195:(e,t,r)=>{r.d(t,{Z:()=>i});const i=r.p+"assets/images/multi-cluster-dd1d21f51c8f0d0623e575b53e84568d.png"}}]); \ No newline at end of file diff --git a/assets/js/21fbcd7c.93f9340a.js b/assets/js/21fbcd7c.9ffb4529.js similarity index 99% rename from assets/js/21fbcd7c.93f9340a.js rename to assets/js/21fbcd7c.9ffb4529.js index bf94db25d..d66acde09 100644 --- a/assets/js/21fbcd7c.93f9340a.js +++ b/assets/js/21fbcd7c.9ffb4529.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[3563],{3905:(t,e,a)=>{a.d(e,{Zo:()=>m,kt:()=>k});var r=a(7294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function i(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,r)}return a}function o(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var p=r.createContext({}),c=function(t){var e=r.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},m=function(t){var e=c(t.components);return r.createElement(p.Provider,{value:e},t.children)},s={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,i=t.originalType,p=t.parentName,m=l(t,["components","mdxType","originalType","parentName"]),d=c(a),k=n,g=d["".concat(p,".").concat(k)]||d[k]||s[k]||i;return a?r.createElement(g,o(o({ref:e},m),{},{components:a})):r.createElement(g,o({ref:e},m))}));function k(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var i=a.length,o=new Array(i);o[0]=d;var l={};for(var p in e)hasOwnProperty.call(e,p)&&(l[p]=e[p]);l.originalType=t,l.mdxType="string"==typeof t?t:n,o[1]=l;for(var c=2;c{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>o,default:()=>s,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=a(7462),n=(a(7294),a(3905));const i={slug:"architecture",title:"Otomi Projects",sidebar_label:"Otomi Projects"},o=void 0,l={unversionedId:"architecture",id:"architecture",title:"Otomi Projects",description:"Otomi consists out of the following projects:",source:"@site/product/architecture.md",sourceDirName:".",slug:"/architecture",permalink:"/product/architecture",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/architecture.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"architecture",title:"Otomi Projects",sidebar_label:"Otomi Projects"},sidebar:"mainSidebar",previous:{title:"Why Otomi",permalink:"/product/introduction"},next:{title:"Roadmap",permalink:"/product/roadmap"}},p={},c=[{value:"Otomi Core",id:"otomi-core",level:2},{value:"Integrated K8s applications",id:"integrated-k8s-applications",level:3},{value:"Catagories",id:"catagories",level:3},{value:"Advanced ingress architecture as its core",id:"advanced-ingress-architecture-as-its-core",level:3},{value:"Otomi Tasks",id:"otomi-tasks",level:2},{value:"Otomi Clients",id:"otomi-clients",level:2},{value:"Otomi API",id:"otomi-api",level:2},{value:"Otomi Console",id:"otomi-console",level:2}],m={toc:c};function s(t){let{components:e,...i}=t;return(0,n.kt)("wrapper",(0,r.Z)({},m,i,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Otomi consists out of the following projects:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Project"),(0,n.kt)("th",{parentName:"tr",align:null},"open source"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-core"},"otomi-core")),(0,n.kt)("td",{parentName:"tr",align:null},"Yes")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-tasks"},"otomi-tasks")),(0,n.kt)("td",{parentName:"tr",align:null},"Yes")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-clients"},"otomi-clients")),(0,n.kt)("td",{parentName:"tr",align:null},"Yes")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-console"},"otomi-console")),(0,n.kt)("td",{parentName:"tr",align:null},"No")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-api"},"otomi-api")),(0,n.kt)("td",{parentName:"tr",align:null},"No")))),(0,n.kt)("h2",{id:"otomi-core"},"Otomi Core"),(0,n.kt)("p",null,"Otomi Core contains all the integrated applications and is made available (per release) as a container image."),(0,n.kt)("p",null,"Otomi Core also contains the source code for Otomi CLI. Otomi CLI can be used for advanced initial configuration (bootstrapping), deployment, sync, push, template validation, and much more."),(0,n.kt)("h3",{id:"integrated-k8s-applications"},"Integrated K8s applications"),(0,n.kt)("p",null,"Otomi Core is the heart of Otomi and contains a suite of the following integrated Kubernetes applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/istio/istio"},"Istio"),": The service mesh framework with end-to-end transit encryption"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/vmware-tanzu/velero"},"Velero"),": Back up and restore your Kubernetes cluster resources and persistent volumes"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/argoproj/argo-cd"},"Argo CD"),": Declarative continuous deployment"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openclarity/kubeclarity"},"KubeClarity"),": Detect vulnerabilities of container images"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/knative/serving"},"Knative"),": Deploy and manage serverless workloads"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/prometheus/prometheus"},"Prometheus"),": Collecting container application metrics"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/grafana/loki"},"Loki"),": Collecting container application logs"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/goharbor/harbor"},"Harbor"),": Container image registry with role-based access control, image scanning, and image signing"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hashicorp/vault"},"HashiCorp Vault"),": Manage Secrets and Protect Sensitive Data"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/vmware-tanzu/kubeapps"},"Kubeapps"),": Launching and managing applications on Kubernetes"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/keycloak/keycloak"},"Keycloak"),": Identity and access management for modern applications and services"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/open-policy-agent/opa"},"OPA"),": Policy-based control for cloud-native environments"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://letsencrypt.org/"},"Let's Encrypt"),": A nonprofit Certificate Authority providing industry-recognized TLS certificates"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/jaegertracing/jaeger"},"Jaeger"),": End-to-end distributed tracing and monitor for complex distributed systems"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/kiali/kiali"},"Kiali"),": Observe Istio service mesh relations and connections"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/kubernetes-sigs/external-dns"},"External DNS"),": Synchronize exposed ingresses with DNS providers"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/harness/drone"},"Drone"),": Continuous integration platform built on Docker"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-gitea/gitea"},"Gitea"),": Self-hosted Git service"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/kubernetes/ingress-nginx"},"Nginx Ingress Controller"),": Ingress controller for Kubernetes"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/minio/minio"},"Minio"),": High performance Object Storage compatible with Amazon S3 cloud storage service")),(0,n.kt)("h3",{id:"catagories"},"Catagories"),(0,n.kt)("p",null,"Otomi contains four catagories of integrated K8s applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Core applications: applications that are activated by default"),(0,n.kt)("li",{parentName:"ul"},"Shared applications: applications that are shared between teams. Shared applications are user-, and role-aware or not (user is anonymous)"),(0,n.kt)("li",{parentName:"ul"},"Team applications: applications with a dedicated instance per team"),(0,n.kt)("li",{parentName:"ul"},"Optional applications: applications that are optional and can be activated by the platform admin")),(0,n.kt)("p",null,"The following table shows all integrated applications:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:"left"},"Application"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Core"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Shared"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Team"),(0,n.kt)("th",{parentName:"tr",align:"center"},"User/role-aware"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Optional"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Istio"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Ingress NGINX Controller"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Knative"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/keycloak"},"KeyCloak")),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Prometheus Server"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Prometheus kube state metrics"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Alertmanager"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Grafana/Loki"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/gatekeeper"},"Gatekeeper Operator")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/vault"},"Hashicorp Vault")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/harbor"},"Harbor")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/kubeapps"},"Kubeapps")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/drone"},"Drone")),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Gitea"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Httpbin"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Jeager"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Kiali"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"KubeClarity"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Velero"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Minio"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Opencost"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Tekton Pipeline"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Trivy Operator"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")))),(0,n.kt)("h3",{id:"advanced-ingress-architecture-as-its-core"},"Advanced ingress architecture as its core"),(0,n.kt)("p",null,"Otomi by default installs and configures an advanced ingress architecture. Ingress for a service can be configured using Otomi Services. The following figure shows the ingress and SSO architecture."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"img/ingress-overview",src:a(2701).Z,width:"1149",height:"828"})),(0,n.kt)("p",null,"The ingress & SSO architecture overview explained:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"(optional) an external gateway is used for termination of external traffic (e.g. an Azure Application Gateway or an AWS Application Load Balancer)."),(0,n.kt)("li",{parentName:"ul"},"2 Ingress NGINX controllers are deployed, one for public access and one for authenticated access."),(0,n.kt)("li",{parentName:"ul"},"Authenticated (SSO) access is handled by an oauth2 proxy and KeyCloak. The user logs in using the Otomi custom KeyCloak login page. "),(0,n.kt)("li",{parentName:"ul"},"KeyCloak is configured with an external IDP (optional) or uses local accounts. After authentication, KeyCloak provides a normalized JWT token. The JWT token is used by integrated core applications (providing user and role information) and team services configured with SSO"),(0,n.kt)("li",{parentName:"ul"},"4 Istio (ingress) gateways are provisioned: ")),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"a public gateway for routing public (non authenticated traffic to a service)"),(0,n.kt)("li",{parentName:"ol"},"an authentication gateway to route authenticated traffic to a service"),(0,n.kt)("li",{parentName:"ol"},"a local gateway (for local cluster routing)"),(0,n.kt)("li",{parentName:"ol"},"a Knative gateway to route traffic to Knative services")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"For each service a Istio virtual service is configured."),(0,n.kt)("li",{parentName:"ul"},"One egress gateway is provisioned for all egress traffic (network policies allow all egress traffic).")),(0,n.kt)("h2",{id:"otomi-tasks"},"Otomi Tasks"),(0,n.kt)("p",null,"Otomi Tasks contains a set of Kubernetes jobs. These jobs ensure that the configuration of applications integrated in Otomi are always equal to the desired-state configuration (see Otomi Values). An example: If a team is created via Otomi Console (in combination with Otomi API), Otomi Tasks ensures that a project is created for the new team in Harbor, the access to the project in Harbor is configured, a robot account (that can be used to push images to the project registry) is created and that a pull secret is created in the namespace of the team."),(0,n.kt)("p",null,"Otomi Tasks is currently used to configure the following applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"KeyCloak"),(0,n.kt)("li",{parentName:"ul"},"Harbor"),(0,n.kt)("li",{parentName:"ul"},"Gitea"),(0,n.kt)("li",{parentName:"ul"},"Drone"),(0,n.kt)("li",{parentName:"ul"},"Otomi (copy-certs and wait-for)")),(0,n.kt)("h2",{id:"otomi-clients"},"Otomi Clients"),(0,n.kt)("p",null,"A factory to build and publish openapi clients used in the redkubes/otomi-tasks repo."),(0,n.kt)("p",null,"Otomi Clients is currently used to generate openapi clients for the following applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"KeyCloak"),(0,n.kt)("li",{parentName:"ul"},"Harbor"),(0,n.kt)("li",{parentName:"ul"},"Gitea")),(0,n.kt)("h2",{id:"otomi-api"},"Otomi API"),(0,n.kt)("p",null,"Otomi API allows for a controlled change of all Otomi Values, based on a configuration scheme and is the brain of Otomi. Otomi API runs as a container on each cluster running."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"Otomi API is not open source. When installing Otomi, a FREE Community Edition version is installed. Contact ",(0,n.kt)("a",{parentName:"p",href:"https://redkubes.com/"},"Red Kubes")," for details on support and pricing for a full featured version.")),(0,n.kt)("h2",{id:"otomi-console"},"Otomi Console"),(0,n.kt)("p",null,"Otomi Console is the User Interface of Otomi. Otomi Console communicates with Otomi API for reading and changing Otomi Values configuration. Otomi Console also offers (via the Otomi Apps option) shortcuts to the UI of the various integrated applications."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"Otomi Console is not open source. When installing Otomi, a FREE Community Edition version is installed. Contact ",(0,n.kt)("a",{parentName:"p",href:"https://redkubes.com/"},"Red Kubes")," for details on support and pricing for a full featured version.")))}s.isMDXComponent=!0},2701:(t,e,a)=>{a.d(e,{Z:()=>r});const r=a.p+"assets/images/ingress-overview-419bc5e7be19dafdebd9a8ec6b04a3b1.svg"}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[3563],{3905:(t,e,a)=>{a.d(e,{Zo:()=>m,kt:()=>k});var r=a(7294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function i(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,r)}return a}function o(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var p=r.createContext({}),c=function(t){var e=r.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},m=function(t){var e=c(t.components);return r.createElement(p.Provider,{value:e},t.children)},s={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,i=t.originalType,p=t.parentName,m=l(t,["components","mdxType","originalType","parentName"]),d=c(a),k=n,g=d["".concat(p,".").concat(k)]||d[k]||s[k]||i;return a?r.createElement(g,o(o({ref:e},m),{},{components:a})):r.createElement(g,o({ref:e},m))}));function k(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var i=a.length,o=new Array(i);o[0]=d;var l={};for(var p in e)hasOwnProperty.call(e,p)&&(l[p]=e[p]);l.originalType=t,l.mdxType="string"==typeof t?t:n,o[1]=l;for(var c=2;c{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>o,default:()=>s,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=a(7462),n=(a(7294),a(3905));const i={slug:"architecture",title:"Otomi Projects",sidebar_label:"Otomi Projects"},o=void 0,l={unversionedId:"architecture",id:"architecture",title:"Otomi Projects",description:"Otomi consists out of the following projects:",source:"@site/product/architecture.md",sourceDirName:".",slug:"/architecture",permalink:"/product/architecture",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/architecture.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"architecture",title:"Otomi Projects",sidebar_label:"Otomi Projects"},sidebar:"mainSidebar",previous:{title:"Why Otomi",permalink:"/product/introduction"},next:{title:"Roadmap",permalink:"/product/roadmap"}},p={},c=[{value:"Otomi Core",id:"otomi-core",level:2},{value:"Integrated K8s applications",id:"integrated-k8s-applications",level:3},{value:"Catagories",id:"catagories",level:3},{value:"Advanced ingress architecture as its core",id:"advanced-ingress-architecture-as-its-core",level:3},{value:"Otomi Tasks",id:"otomi-tasks",level:2},{value:"Otomi Clients",id:"otomi-clients",level:2},{value:"Otomi API",id:"otomi-api",level:2},{value:"Otomi Console",id:"otomi-console",level:2}],m={toc:c};function s(t){let{components:e,...i}=t;return(0,n.kt)("wrapper",(0,r.Z)({},m,i,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Otomi consists out of the following projects:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Project"),(0,n.kt)("th",{parentName:"tr",align:null},"open source"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-core"},"otomi-core")),(0,n.kt)("td",{parentName:"tr",align:null},"Yes")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-tasks"},"otomi-tasks")),(0,n.kt)("td",{parentName:"tr",align:null},"Yes")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-clients"},"otomi-clients")),(0,n.kt)("td",{parentName:"tr",align:null},"Yes")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-console"},"otomi-console")),(0,n.kt)("td",{parentName:"tr",align:null},"No")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},(0,n.kt)("a",{parentName:"td",href:"https://github.com/redkubes/otomi-api"},"otomi-api")),(0,n.kt)("td",{parentName:"tr",align:null},"No")))),(0,n.kt)("h2",{id:"otomi-core"},"Otomi Core"),(0,n.kt)("p",null,"Otomi Core contains all the integrated applications and is made available (per release) as a container image."),(0,n.kt)("p",null,"Otomi Core also contains the source code for Otomi CLI. Otomi CLI can be used for advanced initial configuration (bootstrapping), deployment, sync, push, template validation, and much more."),(0,n.kt)("h3",{id:"integrated-k8s-applications"},"Integrated K8s applications"),(0,n.kt)("p",null,"Otomi Core is the heart of Otomi and contains a suite of the following integrated Kubernetes applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/istio/istio"},"Istio"),": The service mesh framework with end-to-end transit encryption"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/vmware-tanzu/velero"},"Velero"),": Back up and restore your Kubernetes cluster resources and persistent volumes"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/argoproj/argo-cd"},"Argo CD"),": Declarative continuous deployment"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/openclarity/kubeclarity"},"KubeClarity"),": Detect vulnerabilities of container images"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/knative/serving"},"Knative"),": Deploy and manage serverless workloads"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/prometheus/prometheus"},"Prometheus"),": Collecting container application metrics"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/grafana/loki"},"Loki"),": Collecting container application logs"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/goharbor/harbor"},"Harbor"),": Container image registry with role-based access control, image scanning, and image signing"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/hashicorp/vault"},"HashiCorp Vault"),": Manage Secrets and Protect Sensitive Data"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/vmware-tanzu/kubeapps"},"Kubeapps"),": Launching and managing applications on Kubernetes"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/keycloak/keycloak"},"Keycloak"),": Identity and access management for modern applications and services"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/open-policy-agent/opa"},"OPA"),": Policy-based control for cloud-native environments"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://letsencrypt.org/"},"Let's Encrypt"),": A nonprofit Certificate Authority providing industry-recognized TLS certificates"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/jaegertracing/jaeger"},"Jaeger"),": End-to-end distributed tracing and monitor for complex distributed systems"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/kiali/kiali"},"Kiali"),": Observe Istio service mesh relations and connections"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/kubernetes-sigs/external-dns"},"External DNS"),": Synchronize exposed ingresses with DNS providers"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/harness/drone"},"Drone"),": Continuous integration platform built on Docker"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-gitea/gitea"},"Gitea"),": Self-hosted Git service"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/kubernetes/ingress-nginx"},"Nginx Ingress Controller"),": Ingress controller for Kubernetes"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/minio/minio"},"Minio"),": High performance Object Storage compatible with Amazon S3 cloud storage service")),(0,n.kt)("h3",{id:"catagories"},"Catagories"),(0,n.kt)("p",null,"Otomi contains four catagories of integrated K8s applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Core applications: applications that are activated by default"),(0,n.kt)("li",{parentName:"ul"},"Shared applications: applications that are shared between teams. Shared applications are user-, and role-aware or not (user is anonymous)"),(0,n.kt)("li",{parentName:"ul"},"Team applications: applications with a dedicated instance per team"),(0,n.kt)("li",{parentName:"ul"},"Optional applications: applications that are optional and can be activated by the platform admin")),(0,n.kt)("p",null,"The following table shows all integrated applications:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:"left"},"Application"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Core"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Shared"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Team"),(0,n.kt)("th",{parentName:"tr",align:"center"},"User/role-aware"),(0,n.kt)("th",{parentName:"tr",align:"center"},"Optional"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Istio"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Ingress NGINX Controller"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Knative"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/keycloak"},"KeyCloak")),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Prometheus Server"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Prometheus kube state metrics"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Alertmanager"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Grafana/Loki"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/gatekeeper"},"Gatekeeper Operator")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/vault"},"Hashicorp Vault")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/harbor"},"Harbor")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/kubeapps"},"Kubeapps")),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},(0,n.kt)("a",{parentName:"td",href:"/docs/apps/drone"},"Drone")),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Gitea"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Httpbin"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Jeager"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Kiali"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"KubeClarity"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Velero"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Minio"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Opencost"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Tekton Pipeline"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:"left"},"Trivy Operator"),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"}),(0,n.kt)("td",{parentName:"tr",align:"center"},"X")))),(0,n.kt)("h3",{id:"advanced-ingress-architecture-as-its-core"},"Advanced ingress architecture as its core"),(0,n.kt)("p",null,"Otomi by default installs and configures an advanced ingress architecture. Ingress for a service can be configured using Otomi Services. The following figure shows the ingress and SSO architecture."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"img/ingress-overview",src:a(2701).Z,width:"1149",height:"828"})),(0,n.kt)("p",null,"The ingress & SSO architecture overview explained:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"(optional) an external gateway is used for termination of external traffic (e.g. an Azure Application Gateway or an AWS Application Load Balancer)."),(0,n.kt)("li",{parentName:"ul"},"2 Ingress NGINX controllers are deployed, one for public access and one for authenticated access."),(0,n.kt)("li",{parentName:"ul"},"Authenticated (SSO) access is handled by an oauth2 proxy and KeyCloak. The user logs in using the Otomi custom KeyCloak login page. "),(0,n.kt)("li",{parentName:"ul"},"KeyCloak is configured with an external IDP (optional) or uses local accounts. After authentication, KeyCloak provides a normalized JWT token. The JWT token is used by integrated core applications (providing user and role information) and team services configured with SSO"),(0,n.kt)("li",{parentName:"ul"},"4 Istio (ingress) gateways are provisioned: ")),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"a public gateway for routing public (non authenticated traffic to a service)"),(0,n.kt)("li",{parentName:"ol"},"an authentication gateway to route authenticated traffic to a service"),(0,n.kt)("li",{parentName:"ol"},"a local gateway (for local cluster routing)"),(0,n.kt)("li",{parentName:"ol"},"a Knative gateway to route traffic to Knative services")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"For each service a Istio virtual service is configured."),(0,n.kt)("li",{parentName:"ul"},"One egress gateway is provisioned for all egress traffic (network policies allow all egress traffic).")),(0,n.kt)("h2",{id:"otomi-tasks"},"Otomi Tasks"),(0,n.kt)("p",null,"Otomi Tasks contains a set of Kubernetes jobs. These jobs ensure that the configuration of applications integrated in Otomi are always equal to the desired-state configuration (see Otomi Values). An example: If a team is created via Otomi Console (in combination with Otomi API), Otomi Tasks ensures that a project is created for the new team in Harbor, the access to the project in Harbor is configured, a robot account (that can be used to push images to the project registry) is created and that a pull secret is created in the namespace of the team."),(0,n.kt)("p",null,"Otomi Tasks is currently used to configure the following applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"KeyCloak"),(0,n.kt)("li",{parentName:"ul"},"Harbor"),(0,n.kt)("li",{parentName:"ul"},"Gitea"),(0,n.kt)("li",{parentName:"ul"},"Drone"),(0,n.kt)("li",{parentName:"ul"},"Otomi (copy-certs and wait-for)")),(0,n.kt)("h2",{id:"otomi-clients"},"Otomi Clients"),(0,n.kt)("p",null,"A factory to build and publish openapi clients used in the redkubes/otomi-tasks repo."),(0,n.kt)("p",null,"Otomi Clients is currently used to generate openapi clients for the following applications:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"KeyCloak"),(0,n.kt)("li",{parentName:"ul"},"Harbor"),(0,n.kt)("li",{parentName:"ul"},"Gitea")),(0,n.kt)("h2",{id:"otomi-api"},"Otomi API"),(0,n.kt)("p",null,"Otomi API allows for a controlled change of all Otomi Values, based on a configuration scheme and is the brain of Otomi. Otomi API runs as a container on each cluster running."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"Otomi API is not open source. When installing Otomi, a FREE Community Edition version is installed. Contact ",(0,n.kt)("a",{parentName:"p",href:"https://redkubes.com/"},"Red Kubes")," for details on support and pricing for a full featured version.")),(0,n.kt)("h2",{id:"otomi-console"},"Otomi Console"),(0,n.kt)("p",null,"Otomi Console is the User Interface of Otomi. Otomi Console communicates with Otomi API for reading and changing Otomi Values configuration. Otomi Console also offers (via the Otomi Apps option) shortcuts to the UI of the various integrated applications."),(0,n.kt)("admonition",{type:"info"},(0,n.kt)("p",{parentName:"admonition"},"Otomi Console is not open source. When installing Otomi, a FREE Community Edition version is installed. Contact ",(0,n.kt)("a",{parentName:"p",href:"https://redkubes.com/"},"Red Kubes")," for details on support and pricing for a full featured version.")))}s.isMDXComponent=!0},2701:(t,e,a)=>{a.d(e,{Z:()=>r});const r=a.p+"assets/images/ingress-overview-419bc5e7be19dafdebd9a8ec6b04a3b1.svg"}}]); \ No newline at end of file diff --git a/assets/js/2d9c895d.8abc4d81.js b/assets/js/2d9c895d.a3846c17.js similarity index 98% rename from assets/js/2d9c895d.8abc4d81.js rename to assets/js/2d9c895d.a3846c17.js index 82b7456f7..2092a848d 100644 --- a/assets/js/2d9c895d.8abc4d81.js +++ b/assets/js/2d9c895d.a3846c17.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[5022],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),u=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=u(r),m=o,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const a={slug:"overview",title:"Use cases overview",sidebar_label:"Overview"},i=void 0,s={unversionedId:"use-cases/overview",id:"use-cases/overview",title:"Use cases overview",description:"Introduction",source:"@site/product/use-cases/overview.md",sourceDirName:"use-cases",slug:"/use-cases/overview",permalink:"/product/use-cases/overview",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/overview.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"overview",title:"Use cases overview",sidebar_label:"Overview"},sidebar:"mainSidebar",previous:{title:"FAQ",permalink:"/product/faq"},next:{title:"Adoption Framework",permalink:"/product/use-cases/adoption-framework"}},c={},u=[{value:"Introduction",id:"introduction",level:2}],l={toc:u};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"Otomi adds developer- and operations-centric tools, automation and self-service on top of Kubernetes. It contains a complete suite of pre-configured tools and guardrails to run containerized applications securely on any Kubernetes cluster in any cloud. In this section we'll dive a little deeper into the use cases Otomi supports."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/adoption-framework"},"Adoption framework for Kubernetes"),": Use Otomi as an adoption framework to support migration to Kubernetes in an efficient and streamlined way"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/multi-tenancy"},"Multi-tenancy"),": Share a Kubernetes cluster and all the integrated tools with multiple tenants"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/serverless"},"Serverless"),": Use Otomi as a landing zone for serverless applications"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/ci-cd"},"CD/CD"),": Use the CI and CD capabilities of Otomi")),(0,o.kt)("p",null,"The usage of Otomi is not limited to these 5 described use cases. Combine use cases to create your ideal setup."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[5022],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),u=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(c.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=u(r),m=o,f=d["".concat(c,".").concat(m)]||d[m]||p[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var u=2;u{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const a={slug:"overview",title:"Use cases overview",sidebar_label:"Overview"},i=void 0,s={unversionedId:"use-cases/overview",id:"use-cases/overview",title:"Use cases overview",description:"Introduction",source:"@site/product/use-cases/overview.md",sourceDirName:"use-cases",slug:"/use-cases/overview",permalink:"/product/use-cases/overview",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/overview.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"overview",title:"Use cases overview",sidebar_label:"Overview"},sidebar:"mainSidebar",previous:{title:"FAQ",permalink:"/product/faq"},next:{title:"Adoption Framework",permalink:"/product/use-cases/adoption-framework"}},c={},u=[{value:"Introduction",id:"introduction",level:2}],l={toc:u};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"Otomi adds developer- and operations-centric tools, automation and self-service on top of Kubernetes. It contains a complete suite of pre-configured tools and guardrails to run containerized applications securely on any Kubernetes cluster in any cloud. In this section we'll dive a little deeper into the use cases Otomi supports."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/adoption-framework"},"Adoption framework for Kubernetes"),": Use Otomi as an adoption framework to support migration to Kubernetes in an efficient and streamlined way"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/multi-tenancy"},"Multi-tenancy"),": Share a Kubernetes cluster and all the integrated tools with multiple tenants"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/serverless"},"Serverless"),": Use Otomi as a landing zone for serverless applications"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/product/use-cases/ci-cd"},"CD/CD"),": Use the CI and CD capabilities of Otomi")),(0,o.kt)("p",null,"The usage of Otomi is not limited to these 5 described use cases. Combine use cases to create your ideal setup."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/344c6a23.7f64a513.js b/assets/js/344c6a23.7f64a513.js new file mode 100644 index 000000000..f47668988 --- /dev/null +++ b/assets/js/344c6a23.7f64a513.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2358],{3905:(e,t,i)=>{i.d(t,{Zo:()=>s,kt:()=>m});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function l(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var d=n.createContext({}),p=function(e){var t=n.useContext(d),i=t;return e&&(i="function"==typeof e?e(t):r(r({},t),e)),i},s=function(e){var t=p(e.components);return n.createElement(d.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,l=e.originalType,d=e.parentName,s=o(e,["components","mdxType","originalType","parentName"]),c=p(i),m=a,h=c["".concat(d,".").concat(m)]||c[m]||u[m]||l;return i?n.createElement(h,r(r({ref:t},s),{},{components:i})):n.createElement(h,r({ref:t},s))}));function m(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=i.length,r=new Array(l);r[0]=c;var o={};for(var d in t)hasOwnProperty.call(t,d)&&(o[d]=t[d]);o.originalType=e,o.mdxType="string"==typeof e?e:a,r[1]=o;for(var p=2;p{i.r(t),i.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var n=i(7462),a=(i(7294),i(3905));const l={slug:"lab-26",title:"Trigger builds",sidebar_label:"Trigger builds"},r=void 0,o={unversionedId:"for-devs/get-started/lab-26",id:"for-devs/get-started/lab-26",title:"Trigger builds",description:"In the previous lab we created a build in Otomi using a public code repository. In this lab we'll create a build based on a private code repo in the local Gitea and trigger the build based on a webhook.",source:"@site/docs/for-devs/get-started/lab-26.md",sourceDirName:"for-devs/get-started",slug:"/for-devs/get-started/lab-26",permalink:"/docs/for-devs/get-started/lab-26",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/tree/main/docs/for-devs/get-started/lab-26.md",tags:[],version:"current",frontMatter:{slug:"lab-26",title:"Trigger builds",sidebar_label:"Trigger builds"},sidebar:"mainSidebar",previous:{title:"Build images with Otomi",permalink:"/docs/for-devs/get-started/lab-6"},next:{title:"Scan images",permalink:"/docs/for-devs/get-started/lab-7"}},d={},p=[{value:"Create private repo in Gitea",id:"create-private-repo-in-gitea",level:2},{value:"Create a build in Otomi with Trigger enabled",id:"create-a-build-in-otomi-with-trigger-enabled",level:2},{value:"Create a Webhook",id:"create-a-webhook",level:2},{value:"Trigger the build",id:"trigger-the-build",level:2},{value:"Check the status of the build",id:"check-the-status-of-the-build",level:2}],s={toc:p};function u(e){let{components:t,...i}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"In the previous lab we created a build in Otomi using a public code repository. In this lab we'll create a build based on a private code repo in the local Gitea and trigger the build based on a webhook."),(0,a.kt)("h2",{id:"create-private-repo-in-gitea"},"Create private repo in Gitea"),(0,a.kt)("p",null,"First create a private repo in Gitea and mirror a sample repo:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Create a private repo ",(0,a.kt)("inlineCode",{parentName:"li"},"hello")," in the ",(0,a.kt)("inlineCode",{parentName:"li"},"otomi")," organization in Gitea as described in the ",(0,a.kt)("a",{parentName:"li",href:"/docs/for-devs/get-started/lab-3"},"Create a private Git repo")," lab."),(0,a.kt)("li",{parentName:"ul"},"Clone the sample repo:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/redkubes/nodejs-helloworld.git\ncd nodejs-helloworld\n")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Mirror the sample repo to the new Gitea repo:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"git push --mirror https://gitea./otomi/hello.git\n")),(0,a.kt)("h2",{id:"create-a-build-in-otomi-with-trigger-enabled"},"Create a build in Otomi with Trigger enabled"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"In the right menu, click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Build")),(0,a.kt)("li",{parentName:"ol"},"Click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Create Build")),(0,a.kt)("li",{parentName:"ol"},"Fill in the name ",(0,a.kt)("inlineCode",{parentName:"li"},"hello")," for your build and a tag (default is tag is latest)"),(0,a.kt)("li",{parentName:"ol"},"Choose ",(0,a.kt)("inlineCode",{parentName:"li"},"./Dockerfile")),(0,a.kt)("li",{parentName:"ol"},"In the ",(0,a.kt)("inlineCode",{parentName:"li"},"Application source")," section, fill in the following:")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"RepoURL: ",(0,a.kt)("inlineCode",{parentName:"li"},"https://gitea./otomi/hello.git")),(0,a.kt)("li",{parentName:"ul"},"revision: ",(0,a.kt)("inlineCode",{parentName:"li"},"main"))),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Enable ",(0,a.kt)("inlineCode",{parentName:"li"},"Trigger")),(0,a.kt)("li",{parentName:"ol"},"Copy the link in the description ",(0,a.kt)("inlineCode",{parentName:"li"},"(http://el-gitea-webhook-.team-.svc.cluster.local:8080)")),(0,a.kt)("li",{parentName:"ol"},"Click ",(0,a.kt)("inlineCode",{parentName:"li"},"Submit"))),(0,a.kt)("h2",{id:"create-a-webhook"},"Create a Webhook"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"In Otomi Console, click on ",(0,a.kt)("inlineCode",{parentName:"li"},"apps")," the left menu and then open ",(0,a.kt)("inlineCode",{parentName:"li"},"Gitea")),(0,a.kt)("li",{parentName:"ol"},"In the top menu of Gitea, click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Explore")," and then on the ",(0,a.kt)("inlineCode",{parentName:"li"},"otomi/hello")," repo"),(0,a.kt)("li",{parentName:"ol"},"Go to ",(0,a.kt)("inlineCode",{parentName:"li"},"Settings")," (top right) and then to ",(0,a.kt)("inlineCode",{parentName:"li"},"Webhooks")),(0,a.kt)("li",{parentName:"ol"},"Click ",(0,a.kt)("inlineCode",{parentName:"li"},"Add Webhook")," and select ",(0,a.kt)("inlineCode",{parentName:"li"},"Gitea")),(0,a.kt)("li",{parentName:"ol"},"In the ",(0,a.kt)("inlineCode",{parentName:"li"},"Target URL"),", add the link we copied when we created a build in Otomi and adjust the URL based on your team-name. Example: the team name is ",(0,a.kt)("inlineCode",{parentName:"li"},"demo"),", so the URL should be: ",(0,a.kt)("inlineCode",{parentName:"li"},"http://el-gitea-webhook-hello.team-demo.svc.cluster.local:8080")),(0,a.kt)("li",{parentName:"ol"},"Click ",(0,a.kt)("inlineCode",{parentName:"li"},"Add Webhook"))),(0,a.kt)("h2",{id:"trigger-the-build"},"Trigger the build"),(0,a.kt)("p",null,"You can now trigger the build by doing a commit in the ",(0,a.kt)("inlineCode",{parentName:"p"},"hello")," repo, or by testing the webhook. Let's test the webhook"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"In Gitea, go to the ",(0,a.kt)("inlineCode",{parentName:"li"},"Settings")," (top right) of the ",(0,a.kt)("inlineCode",{parentName:"li"},"hello")," repo and then to ",(0,a.kt)("inlineCode",{parentName:"li"},"Webhooks")),(0,a.kt)("li",{parentName:"ol"},"Click on the webhook we just created"),(0,a.kt)("li",{parentName:"ol"},"In the bottom, click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Test Delivery"))),(0,a.kt)("h2",{id:"check-the-status-of-the-build"},"Check the status of the build"),(0,a.kt)("p",null,"The build should now have started. For this, Otomi created a pipeline in Tekton. Based on the webhook, Tekton has now created a ",(0,a.kt)("inlineCode",{parentName:"p"},"PipelineRun"),". Let's check the status of the PipelineRun:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"In Otomi Console, click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Builds")),(0,a.kt)("li",{parentName:"ol"},"In the list of Builds, click on the ",(0,a.kt)("inlineCode",{parentName:"li"},"PipelineRun")," link of the ",(0,a.kt)("inlineCode",{parentName:"li"},"hello")," build"),(0,a.kt)("li",{parentName:"ol"},"Tekton Dashboard will open and show a list of all the PipelineRuns"),(0,a.kt)("li",{parentName:"ol"},"Click on the PipelineRun with the name ",(0,a.kt)("inlineCode",{parentName:"li"},"docker-trigger-build-hello-*")),(0,a.kt)("li",{parentName:"ol"},"You can now see the status of the build.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3d235714.f1f69366.js b/assets/js/3d235714.4f730946.js similarity index 98% rename from assets/js/3d235714.f1f69366.js rename to assets/js/3d235714.4f730946.js index d87e8d538..858cba5d5 100644 --- a/assets/js/3d235714.f1f69366.js +++ b/assets/js/3d235714.4f730946.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2117],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);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 o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),f=a,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||o;return n?r.createElement(m,i(i({ref:t},p),{},{components:n})):r.createElement(m,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const o={slug:"adoption-framework",title:"Otomi as adoption framework for Kubernetes",sidebar_label:"Adoption Framework"},i=void 0,s={unversionedId:"use-cases/adoption-framework",id:"use-cases/adoption-framework",title:"Otomi as adoption framework for Kubernetes",description:"What is an adoption framework for Kubernetes?",source:"@site/product/use-cases/adoption-framework.md",sourceDirName:"use-cases",slug:"/use-cases/adoption-framework",permalink:"/product/use-cases/adoption-framework",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/adoption-framework.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"adoption-framework",title:"Otomi as adoption framework for Kubernetes",sidebar_label:"Adoption Framework"},sidebar:"mainSidebar",previous:{title:"Overview",permalink:"/product/use-cases/overview"},next:{title:"Multi-tenancy",permalink:"/product/use-cases/multi-tenancy"}},l={},c=[{value:"What is an adoption framework for Kubernetes?",id:"what-is-an-adoption-framework-for-kubernetes",level:2},{value:"Why use an adoption framework like Otomi for Kubernetes",id:"why-use-an-adoption-framework-like-otomi-for-kubernetes",level:2},{value:"What are the capabilities of an adoption framework for Kubernetes?",id:"what-are-the-capabilities-of-an-adoption-framework-for-kubernetes",level:2}],p={toc:c};function d(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"what-is-an-adoption-framework-for-kubernetes"},"What is an adoption framework for Kubernetes?"),(0,a.kt)("p",null,"A Kubernetes adoption framework can be used to support migration to Kubernetes in an efficient and streamlined way. The benefit of a Kubernetes adoption framework is that a number of required capabilities and configurations are established initially, which determine how containerized applications are going to be deployed, secured and operated. A Kubernetes adoption framework provides all the required controls following best practices in the areas of security, compliance, observability, CD, networking and self-service. All based on Infrastructure as Code."),(0,a.kt)("p",null,"A Kubernetes adoption framework is implemented differently for each organization. Each company has different requirements, has to meet different compliance requirements, and uses different cloud infrastructures. Creating a multi-/hybrid cloud Kubernetes landing zone requires a significant investment. Otomi can be used as a Kubernetes adoption framework to create a landing zone for containerized applications on any Kubernetes cluster in any cloud and can be tailored based on organization specific requirements."),(0,a.kt)("h2",{id:"why-use-an-adoption-framework-like-otomi-for-kubernetes"},"Why use an adoption framework like Otomi for Kubernetes"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Compliant With Security Regulations\nGiven that established parameters apply, developers operate within well-defined boundaries. This means that companies do not risk of running containerized workloads that differ from their compliance policy. Similarly, the IT manager is less concerned about compliance as it is embedded in the foundation of the IT infrastructure.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Speed \u200b\u200bAnd Scalability\nAs mentioned above, a migration to Kubernetes can happen more quickly with the help of an adoption framework. Preparation time is significantly reduced. Creating a compliant landigzone for Kubernetes can take up to 12 months (or even more) of work (if you have the required knowledge onboard). This time can be cut down to days with the use of Otomi, resulting in considerable cost savings as well as a shorter time-to-market for new applications and more efficiently DevOps processes. Another key feature inherent in Otomi as an adoption framework is scalability, as it is easy to expand to new environments. It allows the development of standard profiles easily for new Kubernetes clusters in any cloud.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Security And Compliance\nThanks to guardrails, compliance is an integral part of Otomi, meaning developers and engineers can safely operate containerized workloads on Kubernetes and in observance of compliance regulations. What\u2019s more, organizations don\u2019t spend that much time implementing complex configurations with the risk of technical debt. This especially applies to the operational phase. But it doesn\u2019t stop with a one-off setting of the environment. It is also about keeping all environments up to date in an ongoing and consistent way.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"A Better Understanding Of Costs\nOrganizations quickly lose control of their engineering expenses because they don\u2019t have a clear overview of the technologies being used and their costs. Otomi reduces unexpected and unnecessary expenses.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Standardized For Multi-Tenancy\nIn a multi-tenant architecture, standardizing tenancy allows you to enforce policies to a group of users. It helps you set up different security profiles and provide access to shared tools with users having specific privileges."))),(0,a.kt)("h2",{id:"what-are-the-capabilities-of-an-adoption-framework-for-kubernetes"},"What are the capabilities of an adoption framework for Kubernetes?"),(0,a.kt)("p",null,"The following picture shows all the required capabilities for a Kubernetes adoption framework, which are all incorporated into Otomi:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"capabilities",src:n(7089).Z,width:"1788",height:"2326"})))}d.isMDXComponent=!0},7089:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/capabilities-aad63fbe048136bfcc184af026171b32.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2117],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);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 o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),f=a,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||o;return n?r.createElement(m,i(i({ref:t},p),{},{components:n})):r.createElement(m,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const o={slug:"adoption-framework",title:"Otomi as adoption framework for Kubernetes",sidebar_label:"Adoption Framework"},i=void 0,s={unversionedId:"use-cases/adoption-framework",id:"use-cases/adoption-framework",title:"Otomi as adoption framework for Kubernetes",description:"What is an adoption framework for Kubernetes?",source:"@site/product/use-cases/adoption-framework.md",sourceDirName:"use-cases",slug:"/use-cases/adoption-framework",permalink:"/product/use-cases/adoption-framework",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/adoption-framework.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"adoption-framework",title:"Otomi as adoption framework for Kubernetes",sidebar_label:"Adoption Framework"},sidebar:"mainSidebar",previous:{title:"Overview",permalink:"/product/use-cases/overview"},next:{title:"Multi-tenancy",permalink:"/product/use-cases/multi-tenancy"}},l={},c=[{value:"What is an adoption framework for Kubernetes?",id:"what-is-an-adoption-framework-for-kubernetes",level:2},{value:"Why use an adoption framework like Otomi for Kubernetes",id:"why-use-an-adoption-framework-like-otomi-for-kubernetes",level:2},{value:"What are the capabilities of an adoption framework for Kubernetes?",id:"what-are-the-capabilities-of-an-adoption-framework-for-kubernetes",level:2}],p={toc:c};function d(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"what-is-an-adoption-framework-for-kubernetes"},"What is an adoption framework for Kubernetes?"),(0,a.kt)("p",null,"A Kubernetes adoption framework can be used to support migration to Kubernetes in an efficient and streamlined way. The benefit of a Kubernetes adoption framework is that a number of required capabilities and configurations are established initially, which determine how containerized applications are going to be deployed, secured and operated. A Kubernetes adoption framework provides all the required controls following best practices in the areas of security, compliance, observability, CD, networking and self-service. All based on Infrastructure as Code."),(0,a.kt)("p",null,"A Kubernetes adoption framework is implemented differently for each organization. Each company has different requirements, has to meet different compliance requirements, and uses different cloud infrastructures. Creating a multi-/hybrid cloud Kubernetes landing zone requires a significant investment. Otomi can be used as a Kubernetes adoption framework to create a landing zone for containerized applications on any Kubernetes cluster in any cloud and can be tailored based on organization specific requirements."),(0,a.kt)("h2",{id:"why-use-an-adoption-framework-like-otomi-for-kubernetes"},"Why use an adoption framework like Otomi for Kubernetes"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Compliant With Security Regulations\nGiven that established parameters apply, developers operate within well-defined boundaries. This means that companies do not risk of running containerized workloads that differ from their compliance policy. Similarly, the IT manager is less concerned about compliance as it is embedded in the foundation of the IT infrastructure.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Speed \u200b\u200bAnd Scalability\nAs mentioned above, a migration to Kubernetes can happen more quickly with the help of an adoption framework. Preparation time is significantly reduced. Creating a compliant landigzone for Kubernetes can take up to 12 months (or even more) of work (if you have the required knowledge onboard). This time can be cut down to days with the use of Otomi, resulting in considerable cost savings as well as a shorter time-to-market for new applications and more efficiently DevOps processes. Another key feature inherent in Otomi as an adoption framework is scalability, as it is easy to expand to new environments. It allows the development of standard profiles easily for new Kubernetes clusters in any cloud.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Security And Compliance\nThanks to guardrails, compliance is an integral part of Otomi, meaning developers and engineers can safely operate containerized workloads on Kubernetes and in observance of compliance regulations. What\u2019s more, organizations don\u2019t spend that much time implementing complex configurations with the risk of technical debt. This especially applies to the operational phase. But it doesn\u2019t stop with a one-off setting of the environment. It is also about keeping all environments up to date in an ongoing and consistent way.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"A Better Understanding Of Costs\nOrganizations quickly lose control of their engineering expenses because they don\u2019t have a clear overview of the technologies being used and their costs. Otomi reduces unexpected and unnecessary expenses.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Standardized For Multi-Tenancy\nIn a multi-tenant architecture, standardizing tenancy allows you to enforce policies to a group of users. It helps you set up different security profiles and provide access to shared tools with users having specific privileges."))),(0,a.kt)("h2",{id:"what-are-the-capabilities-of-an-adoption-framework-for-kubernetes"},"What are the capabilities of an adoption framework for Kubernetes?"),(0,a.kt)("p",null,"The following picture shows all the required capabilities for a Kubernetes adoption framework, which are all incorporated into Otomi:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"capabilities",src:n(7089).Z,width:"1788",height:"2326"})))}d.isMDXComponent=!0},7089:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/capabilities-aad63fbe048136bfcc184af026171b32.png"}}]); \ No newline at end of file diff --git a/assets/js/4f01d7c7.f025b3e0.js b/assets/js/4f01d7c7.86b2663e.js similarity index 99% rename from assets/js/4f01d7c7.f025b3e0.js rename to assets/js/4f01d7c7.86b2663e.js index e0ea47288..314cf4fa6 100644 --- a/assets/js/4f01d7c7.f025b3e0.js +++ b/assets/js/4f01d7c7.86b2663e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[7015],{3905:(e,t,o)=>{o.d(t,{Zo:()=>d,kt:()=>m});var n=o(7294);function a(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(a[o]=e[o]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(a[o]=e[o])}return a}var l=n.createContext({}),u=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},d=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var o=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=u(o),m=a,h=p["".concat(l,".").concat(m)]||p[m]||c[m]||i;return o?n.createElement(h,r(r({ref:t},d),{},{components:o})):n.createElement(h,r({ref:t},d))}));function m(e,t){var o=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=o.length,r=new Array(i);r[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var u=2;u{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var n=o(7462),a=(o(7294),o(3905));const i={slug:"introduction",title:"Why Otomi",sidebar_label:"Why Otomi"},r=void 0,s={unversionedId:"introduction",id:"introduction",title:"Why Otomi",description:"The vision",source:"@site/product/introduction.md",sourceDirName:".",slug:"/introduction",permalink:"/product/introduction",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/introduction.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"introduction",title:"Why Otomi",sidebar_label:"Why Otomi"},sidebar:"mainSidebar",next:{title:"Otomi Projects",permalink:"/product/architecture"}},l={},u=[{value:"The vision",id:"the-vision",level:2},{value:"What is Otomi?",id:"what-is-otomi",level:2},{value:"What is the difference between an IDP and a PaaS?",id:"what-is-the-difference-between-an-idp-and-a-paas",level:3},{value:"When to build an IDP or use a PaaS?",id:"when-to-build-an-idp-or-use-a-paas",level:3},{value:"Otomi for developers",id:"otomi-for-developers",level:2},{value:"Removing the complexity",id:"removing-the-complexity",level:3},{value:"All the tools you need",id:"all-the-tools-you-need",level:3},{value:"Best practices",id:"best-practices",level:3},{value:"Self-Serving",id:"self-serving",level:3},{value:"Otomi for Platform Teams",id:"otomi-for-platform-teams",level:2},{value:"Avoid Cloud Lock-In",id:"avoid-cloud-lock-in",level:3},{value:"Make Developers Self Serving",id:"make-developers-self-serving",level:3},{value:"Lower The Operational Burden",id:"lower-the-operational-burden",level:3},{value:"Prevent Kubernetes Cluster Sprawl",id:"prevent-kubernetes-cluster-sprawl",level:3}],d={toc:u};function c(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"the-vision"},"The vision"),(0,a.kt)("p",null,"Kubernetes has been called The Operating System of the Cloud. In our opinion, Kubernetes is only the Kernel of the Operating System of the Cloud. The Operating System (or Kubernetes-based Platform) is something you'll need to build yourself. And this is what organizations are now doing when using Kubernetes. All reinventing the wheel."),(0,a.kt)("p",null,"Building a Kubernetes-based platform requires a huge investment and requires skilled engineers. But why would you invest in building and maintaining a custom platform? Why can't you just install everyting you need to turn Kubernetes into a full platform, just like you can download a Linux distribution? "),(0,a.kt)("p",null,"This is what we indended when we created Otomi. Any infrastructure, any K8s, one install, all the tools you need in an integrated and automated way, easy self-service and everything as code."),(0,a.kt)("h2",{id:"what-is-otomi"},"What is Otomi?"),(0,a.kt)("p",null,"Otomi is a self-hosted PaaS and adds developer- and operations-centric tools, automation and self-service on top of Kubernetes offering a multi and hybrid platform experience out-of-the-box. Otomi is placed in the CNCF landscape under the ",(0,a.kt)("a",{parentName:"p",href:"https://landscape.cncf.io/guide#platform--paas-container-service"},"PaaS/Container Service")," section. Otomi attempts to connect many of the technologies found in the CNCF landscape in a way to provide direct value. No more re-inventing the wheel when building and maintaining your own Kubernetes based platform or bespoke stack."),(0,a.kt)("h3",{id:"what-is-the-difference-between-an-idp-and-a-paas"},"What is the difference between an IDP and a PaaS?"),(0,a.kt)("p",null,"An Internal Developer Platform (IDP) consists of many different technologies, glued together to lowers cognitive load on developers without abstracting away context and underlying technologies. An IDP is always custom built."),(0,a.kt)("p",null,"A PaaS for Kubernetes also lowers cognitive load on developers, but abstracts away most of the underlying technologies. Unlike an IDP, a PaaS can be used almost instantly, just like downloading and using your favourite Linux Distribution. Organizations that use a PaaS instead of building an IDP can enjoy lower upfront costs and huge time savings."),(0,a.kt)("h3",{id:"when-to-build-an-idp-or-use-a-paas"},"When to build an IDP or use a PaaS?"),(0,a.kt)("p",null,"Because building an IDP requires a large upfront investment, it\u2019s mostly suitable for large enterprises. For smaller organizations a PaaS can sometimes be far more efficient than building a custom IDP in-house."),(0,a.kt)("h2",{id:"otomi-for-developers"},"Otomi for developers"),(0,a.kt)("p",null,"Otomi let's developers focus on their application, not on writing Kubernetes manifests! Kubernetes is great for running containers, but it's complex. Wouldn't it be awesome if you didn't need to worry about understanding Kubernetes objects and writing YAML manifests?"),(0,a.kt)("p",null,"This is how Otomi helps developers:"),(0,a.kt)("h3",{id:"removing-the-complexity"},"Removing the complexity"),(0,a.kt)("p",null,"As a Developer, you want to focus on your code and don\u2019t be bothered with Kubernetes internals. With Otomi, you can deploy your apps on Kubernetes without needing to understand or learn Kubernetes. Just build your image, push it to a registry in Otomi and use the Web Console to deploy your app in just a couple of minutes. Otomi makes Kubernetes easy!"),(0,a.kt)("h3",{id:"all-the-tools-you-need"},"All the tools you need"),(0,a.kt)("p",null,"Otomi provides developers with all the tools they need. After deploying your app you can directly see all the container logs and metrics. Next to logs and metrics, you will also get access to tools like Kubeapps to quickly deploy apps from a catalog and Hashicorp Vault to store and manage secrets. Secrets stored in Vault can directly be used in your deployments. You will also get access to a project in Harbor and can directly see possible vulnerabilities in container images."),(0,a.kt)("h3",{id:"best-practices"},"Best practices"),(0,a.kt)("p",null,"Otomi offers you the ability to immediately start deploying applications on Kubernetes and configure public exposure. This will give you a jump start to get apps running on Kubernetes. But in time you will probably learn more about Kubernetes and start trying out things yourself. Otomi does not force you to use the Web Console. You can just as easily download the KubeConfig for your team and create and deploy manifests yourself. But Otomi will always force you to adhere to the configured safeguards and best practices."),(0,a.kt)("h3",{id:"self-serving"},"Self-Serving"),(0,a.kt)("p",null,"As a developer, you don\u2019t like to go to the Ops team asking for help. Otomi provides full developer self-service. Developers can spin up new virtual environments, download pull secrets, create Kubernetes secrets, build images from source code, deploy workloads and configure public exposure. And all of these features are accessible through just one Web Console. Now you can deliver code completely autonomously."),(0,a.kt)("h2",{id:"otomi-for-platform-teams"},"Otomi for Platform Teams"),(0,a.kt)("p",null,"If you can\u2019t scale beyond a handful of teams you're going to lose speed. Speed is everything to bring new products and applications to market. No one wants to slow down developers. Empower developers, ensure quality, compliance, and governance, avoid lock-in, and lower the operational burden. These are some of the challenges platform teams have to deal with and where Otomi can help out."),(0,a.kt)("h3",{id:"avoid-cloud-lock-in"},"Avoid Cloud Lock-In"),(0,a.kt)("p",null,"Are you worried that you can\u2019t adopt cloud-native technology without becoming completely reliant on one cloud provider? One way that organizations outsource management for Kubernetes is to use one of the cloud provider\u2019s Kubernetes versions in conjunction with a variety of cloud provider native services. This is often faster than using vanilla Kubernetes and managing integrations and infrastructure in-house, but it also completely locks the organization into the cloud provider and often becomes very expensive."),(0,a.kt)("p",null,"This approach also takes away the flexibility to change cloud providers in the future while increasing the financial risks. With Otomi, you don\u2019t have to lock yourself into any cloud provider or risk rapidly increasing cloud service bills in order to get the fastest possible platform to deploy containerized applications."),(0,a.kt)("h3",{id:"make-developers-self-serving"},"Make Developers Self Serving"),(0,a.kt)("p",null,"Free developers from worrying about the underlying platform setup while still enforcing standards and best practices so they can focus on delivering code. With Otomi, developers can be fully self-serving. They can spin up new namespaces, get access to all the tools they need, build images from source code, create secrets, deploy workloads, configure public exposure, add service monitors, and much more. And all of these features are accessible through just one web UI."),(0,a.kt)("p",null,"Platform administrators have access to all the platform applications. Team administrators can create team spaces for development teams and team members can create multiple namespaces within their team space(s)."),(0,a.kt)("h3",{id:"lower-the-operational-burden"},"Lower The Operational Burden"),(0,a.kt)("p",null,"Choosing the DIY platform engineering approach can be time-consuming and complex. On average, Platform teams need at least 6 months to build an initial setup. And the ongoing maintenance and hardening afterwards can become an operational nightmare. Otomi helps Platform teams to lower the operational burden by taking over the application management of everything running on top of Kubernetes, including the lifecycle management of all the integrated K8s applications."),(0,a.kt)("p",null,"This enables platform teams to focus on another very important aspect: Kubernetes cluster infrastructure management and cloud security. Now you have time to focus on other important aspects instead of building a custom (internal) developer platform solution."),(0,a.kt)("h3",{id:"prevent-kubernetes-cluster-sprawl"},"Prevent Kubernetes Cluster Sprawl"),(0,a.kt)("p",null,"As companies look to further harness the power of cloud-native, they are adopting container technologies at rapid speed, increasing the number of clusters and workloads. As the number of Kubernetes clusters grows, this is creating increased work for Platform teams. When it comes to patching security vulnerabilities or upgrading clusters, teams are doing five times the amount of work."),(0,a.kt)("p",null,"With Otomi you can support (soft) multi-tenancy, allowing multiple development teams to work independently of each other on the same cluster, while sharing all the tools. Now you only have to deploy a single dev or staging cluster to support multiple development teams. This prevents you from Kubernetes cluster sprawl."))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[7015],{3905:(e,t,o)=>{o.d(t,{Zo:()=>d,kt:()=>m});var n=o(7294);function a(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(a[o]=e[o]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(a[o]=e[o])}return a}var l=n.createContext({}),u=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},d=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var o=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=u(o),m=a,h=p["".concat(l,".").concat(m)]||p[m]||c[m]||i;return o?n.createElement(h,r(r({ref:t},d),{},{components:o})):n.createElement(h,r({ref:t},d))}));function m(e,t){var o=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=o.length,r=new Array(i);r[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var u=2;u{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var n=o(7462),a=(o(7294),o(3905));const i={slug:"introduction",title:"Why Otomi",sidebar_label:"Why Otomi"},r=void 0,s={unversionedId:"introduction",id:"introduction",title:"Why Otomi",description:"The vision",source:"@site/product/introduction.md",sourceDirName:".",slug:"/introduction",permalink:"/product/introduction",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/introduction.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"introduction",title:"Why Otomi",sidebar_label:"Why Otomi"},sidebar:"mainSidebar",next:{title:"Otomi Projects",permalink:"/product/architecture"}},l={},u=[{value:"The vision",id:"the-vision",level:2},{value:"What is Otomi?",id:"what-is-otomi",level:2},{value:"What is the difference between an IDP and a PaaS?",id:"what-is-the-difference-between-an-idp-and-a-paas",level:3},{value:"When to build an IDP or use a PaaS?",id:"when-to-build-an-idp-or-use-a-paas",level:3},{value:"Otomi for developers",id:"otomi-for-developers",level:2},{value:"Removing the complexity",id:"removing-the-complexity",level:3},{value:"All the tools you need",id:"all-the-tools-you-need",level:3},{value:"Best practices",id:"best-practices",level:3},{value:"Self-Serving",id:"self-serving",level:3},{value:"Otomi for Platform Teams",id:"otomi-for-platform-teams",level:2},{value:"Avoid Cloud Lock-In",id:"avoid-cloud-lock-in",level:3},{value:"Make Developers Self Serving",id:"make-developers-self-serving",level:3},{value:"Lower The Operational Burden",id:"lower-the-operational-burden",level:3},{value:"Prevent Kubernetes Cluster Sprawl",id:"prevent-kubernetes-cluster-sprawl",level:3}],d={toc:u};function c(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"the-vision"},"The vision"),(0,a.kt)("p",null,"Kubernetes has been called The Operating System of the Cloud. In our opinion, Kubernetes is only the Kernel of the Operating System of the Cloud. The Operating System (or Kubernetes-based Platform) is something you'll need to build yourself. And this is what organizations are now doing when using Kubernetes. All reinventing the wheel."),(0,a.kt)("p",null,"Building a Kubernetes-based platform requires a huge investment and requires skilled engineers. But why would you invest in building and maintaining a custom platform? Why can't you just install everyting you need to turn Kubernetes into a full platform, just like you can download a Linux distribution? "),(0,a.kt)("p",null,"This is what we indended when we created Otomi. Any infrastructure, any K8s, one install, all the tools you need in an integrated and automated way, easy self-service and everything as code."),(0,a.kt)("h2",{id:"what-is-otomi"},"What is Otomi?"),(0,a.kt)("p",null,"Otomi is a self-hosted PaaS and adds developer- and operations-centric tools, automation and self-service on top of Kubernetes offering a multi and hybrid platform experience out-of-the-box. Otomi is placed in the CNCF landscape under the ",(0,a.kt)("a",{parentName:"p",href:"https://landscape.cncf.io/guide#platform--paas-container-service"},"PaaS/Container Service")," section. Otomi attempts to connect many of the technologies found in the CNCF landscape in a way to provide direct value. No more re-inventing the wheel when building and maintaining your own Kubernetes based platform or bespoke stack."),(0,a.kt)("h3",{id:"what-is-the-difference-between-an-idp-and-a-paas"},"What is the difference between an IDP and a PaaS?"),(0,a.kt)("p",null,"An Internal Developer Platform (IDP) consists of many different technologies, glued together to lowers cognitive load on developers without abstracting away context and underlying technologies. An IDP is always custom built."),(0,a.kt)("p",null,"A PaaS for Kubernetes also lowers cognitive load on developers, but abstracts away most of the underlying technologies. Unlike an IDP, a PaaS can be used almost instantly, just like downloading and using your favourite Linux Distribution. Organizations that use a PaaS instead of building an IDP can enjoy lower upfront costs and huge time savings."),(0,a.kt)("h3",{id:"when-to-build-an-idp-or-use-a-paas"},"When to build an IDP or use a PaaS?"),(0,a.kt)("p",null,"Because building an IDP requires a large upfront investment, it\u2019s mostly suitable for large enterprises. For smaller organizations a PaaS can sometimes be far more efficient than building a custom IDP in-house."),(0,a.kt)("h2",{id:"otomi-for-developers"},"Otomi for developers"),(0,a.kt)("p",null,"Otomi let's developers focus on their application, not on writing Kubernetes manifests! Kubernetes is great for running containers, but it's complex. Wouldn't it be awesome if you didn't need to worry about understanding Kubernetes objects and writing YAML manifests?"),(0,a.kt)("p",null,"This is how Otomi helps developers:"),(0,a.kt)("h3",{id:"removing-the-complexity"},"Removing the complexity"),(0,a.kt)("p",null,"As a Developer, you want to focus on your code and don\u2019t be bothered with Kubernetes internals. With Otomi, you can deploy your apps on Kubernetes without needing to understand or learn Kubernetes. Just build your image, push it to a registry in Otomi and use the Web Console to deploy your app in just a couple of minutes. Otomi makes Kubernetes easy!"),(0,a.kt)("h3",{id:"all-the-tools-you-need"},"All the tools you need"),(0,a.kt)("p",null,"Otomi provides developers with all the tools they need. After deploying your app you can directly see all the container logs and metrics. Next to logs and metrics, you will also get access to tools like Kubeapps to quickly deploy apps from a catalog and Hashicorp Vault to store and manage secrets. Secrets stored in Vault can directly be used in your deployments. You will also get access to a project in Harbor and can directly see possible vulnerabilities in container images."),(0,a.kt)("h3",{id:"best-practices"},"Best practices"),(0,a.kt)("p",null,"Otomi offers you the ability to immediately start deploying applications on Kubernetes and configure public exposure. This will give you a jump start to get apps running on Kubernetes. But in time you will probably learn more about Kubernetes and start trying out things yourself. Otomi does not force you to use the Web Console. You can just as easily download the KubeConfig for your team and create and deploy manifests yourself. But Otomi will always force you to adhere to the configured safeguards and best practices."),(0,a.kt)("h3",{id:"self-serving"},"Self-Serving"),(0,a.kt)("p",null,"As a developer, you don\u2019t like to go to the Ops team asking for help. Otomi provides full developer self-service. Developers can spin up new virtual environments, download pull secrets, create Kubernetes secrets, build images from source code, deploy workloads and configure public exposure. And all of these features are accessible through just one Web Console. Now you can deliver code completely autonomously."),(0,a.kt)("h2",{id:"otomi-for-platform-teams"},"Otomi for Platform Teams"),(0,a.kt)("p",null,"If you can\u2019t scale beyond a handful of teams you're going to lose speed. Speed is everything to bring new products and applications to market. No one wants to slow down developers. Empower developers, ensure quality, compliance, and governance, avoid lock-in, and lower the operational burden. These are some of the challenges platform teams have to deal with and where Otomi can help out."),(0,a.kt)("h3",{id:"avoid-cloud-lock-in"},"Avoid Cloud Lock-In"),(0,a.kt)("p",null,"Are you worried that you can\u2019t adopt cloud-native technology without becoming completely reliant on one cloud provider? One way that organizations outsource management for Kubernetes is to use one of the cloud provider\u2019s Kubernetes versions in conjunction with a variety of cloud provider native services. This is often faster than using vanilla Kubernetes and managing integrations and infrastructure in-house, but it also completely locks the organization into the cloud provider and often becomes very expensive."),(0,a.kt)("p",null,"This approach also takes away the flexibility to change cloud providers in the future while increasing the financial risks. With Otomi, you don\u2019t have to lock yourself into any cloud provider or risk rapidly increasing cloud service bills in order to get the fastest possible platform to deploy containerized applications."),(0,a.kt)("h3",{id:"make-developers-self-serving"},"Make Developers Self Serving"),(0,a.kt)("p",null,"Free developers from worrying about the underlying platform setup while still enforcing standards and best practices so they can focus on delivering code. With Otomi, developers can be fully self-serving. They can spin up new namespaces, get access to all the tools they need, build images from source code, create secrets, deploy workloads, configure public exposure, add service monitors, and much more. And all of these features are accessible through just one web UI."),(0,a.kt)("p",null,"Platform administrators have access to all the platform applications. Team administrators can create team spaces for development teams and team members can create multiple namespaces within their team space(s)."),(0,a.kt)("h3",{id:"lower-the-operational-burden"},"Lower The Operational Burden"),(0,a.kt)("p",null,"Choosing the DIY platform engineering approach can be time-consuming and complex. On average, Platform teams need at least 6 months to build an initial setup. And the ongoing maintenance and hardening afterwards can become an operational nightmare. Otomi helps Platform teams to lower the operational burden by taking over the application management of everything running on top of Kubernetes, including the lifecycle management of all the integrated K8s applications."),(0,a.kt)("p",null,"This enables platform teams to focus on another very important aspect: Kubernetes cluster infrastructure management and cloud security. Now you have time to focus on other important aspects instead of building a custom (internal) developer platform solution."),(0,a.kt)("h3",{id:"prevent-kubernetes-cluster-sprawl"},"Prevent Kubernetes Cluster Sprawl"),(0,a.kt)("p",null,"As companies look to further harness the power of cloud-native, they are adopting container technologies at rapid speed, increasing the number of clusters and workloads. As the number of Kubernetes clusters grows, this is creating increased work for Platform teams. When it comes to patching security vulnerabilities or upgrading clusters, teams are doing five times the amount of work."),(0,a.kt)("p",null,"With Otomi you can support (soft) multi-tenancy, allowing multiple development teams to work independently of each other on the same cluster, while sharing all the tools. Now you only have to deploy a single dev or staging cluster to support multiple development teams. This prevents you from Kubernetes cluster sprawl."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5db37859.dca047bb.js b/assets/js/5db37859.60b89ed2.js similarity index 98% rename from assets/js/5db37859.dca047bb.js rename to assets/js/5db37859.60b89ed2.js index 2efe9c38c..630044c2f 100644 --- a/assets/js/5db37859.dca047bb.js +++ b/assets/js/5db37859.60b89ed2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[344],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>d});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var s=n.createContext({}),l=function(e){var t=n.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),m=l(o),d=r,f=m["".concat(s,".").concat(d)]||m[d]||p[d]||i;return o?n.createElement(f,a(a({ref:t},u),{},{components:o})):n.createElement(f,a({ref:t},u))}));function d(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:r,a[1]=c;for(var l=2;l{o.r(t),o.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=o(7462),r=(o(7294),o(3905));const i={title:"Contribution Expectations",slug:"expectations",sidebar_label:"Expectations"},a=void 0,c={unversionedId:"expectations",id:"expectations",title:"Contribution Expectations",description:"Otomi is a community project.",source:"@site/community/expectations.md",sourceDirName:".",slug:"/expectations",permalink:"/community/expectations",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/expectations.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{title:"Contribution Expectations",slug:"expectations",sidebar_label:"Expectations"},sidebar:"mainSidebar",previous:{title:"Code of Conduct",permalink:"/community/code-of-conduct"}},s={},l=[{value:"Code review",id:"code-review",level:2},{value:"Expectations of reviewers",id:"expectations-of-reviewers",level:2},{value:"Review comments",id:"review-comments",level:3},{value:"Review latency",id:"review-latency",level:3},{value:"Thank you",id:"thank-you",level:2}],u={toc:l};function p(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Otomi is a community project.\nConsequently, it is wholly dependent on its community to provide a productive, friendly and collaborative environment."),(0,r.kt)("p",null,"The first and foremost goal of the Otomi community is to develop a stack of configurable k8s applications that work in tandem, in order to give k8s users control over their distributed applications."),(0,r.kt)("p",null,"We therefore describe the expectations for members of the Otomi community.\nThis document is intended to be a living one that evolves as the community evolves via the same PR and code review process that shapes the rest of the project.\nIt currently covers the expectations of conduct that govern all members of the community as well as the expectations around code review that govern all active contributors to Otomi."),(0,r.kt)("h2",{id:"code-review"},"Code review"),(0,r.kt)("p",null,"As a community we believe in the value of code review for all contributions.\nCode review increases both the quality and readability of our codebase, which\nin turn produces high quality software."),(0,r.kt)("p",null,"Consequently, as a community we expect that all active participants in the community will also be active reviewers."),(0,r.kt)("h2",{id:"expectations-of-reviewers"},"Expectations of reviewers"),(0,r.kt)("h3",{id:"review-comments"},"Review comments"),(0,r.kt)("p",null,"Because reviewers are often the first points of contact between new members of the community and can significantly impact the first impression of the Otomi community, reviewers are especially important in shaping the Otomi community. Reviewers are highly encouraged to not only abide by the ",(0,r.kt)("a",{parentName:"p",href:"code-of-conduct"},"code of conduct")," but are strongly encouraged to go above and beyond the code of conduct to promote a collaborative, respectful Otomi community."),(0,r.kt)("h3",{id:"review-latency"},"Review latency"),(0,r.kt)("p",null,"Reviewers are expected to respond in a timely fashion to PRs that are assigned to them. Reviewers are expected to respond to an ",(0,r.kt)("em",{parentName:"p"},"active")," PRs with reasonable latency, and if reviewers fail to respond, those PRs may be assigned to other reviewers."),(0,r.kt)("h2",{id:"thank-you"},"Thank you"),(0,r.kt)("p",null,"We want to thank everyone who contributes their time and effort to making Otomi both a successful endeavour as well as a successful community. The strength of our software lies in the combined strengths of each individual community member. Thanks!"))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[344],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>d});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var s=n.createContext({}),l=function(e){var t=n.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),m=l(o),d=r,f=m["".concat(s,".").concat(d)]||m[d]||p[d]||i;return o?n.createElement(f,a(a({ref:t},u),{},{components:o})):n.createElement(f,a({ref:t},u))}));function d(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:r,a[1]=c;for(var l=2;l{o.r(t),o.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=o(7462),r=(o(7294),o(3905));const i={title:"Contribution Expectations",slug:"expectations",sidebar_label:"Expectations"},a=void 0,c={unversionedId:"expectations",id:"expectations",title:"Contribution Expectations",description:"Otomi is a community project.",source:"@site/community/expectations.md",sourceDirName:".",slug:"/expectations",permalink:"/community/expectations",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/expectations.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{title:"Contribution Expectations",slug:"expectations",sidebar_label:"Expectations"},sidebar:"mainSidebar",previous:{title:"Code of Conduct",permalink:"/community/code-of-conduct"}},s={},l=[{value:"Code review",id:"code-review",level:2},{value:"Expectations of reviewers",id:"expectations-of-reviewers",level:2},{value:"Review comments",id:"review-comments",level:3},{value:"Review latency",id:"review-latency",level:3},{value:"Thank you",id:"thank-you",level:2}],u={toc:l};function p(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Otomi is a community project.\nConsequently, it is wholly dependent on its community to provide a productive, friendly and collaborative environment."),(0,r.kt)("p",null,"The first and foremost goal of the Otomi community is to develop a stack of configurable k8s applications that work in tandem, in order to give k8s users control over their distributed applications."),(0,r.kt)("p",null,"We therefore describe the expectations for members of the Otomi community.\nThis document is intended to be a living one that evolves as the community evolves via the same PR and code review process that shapes the rest of the project.\nIt currently covers the expectations of conduct that govern all members of the community as well as the expectations around code review that govern all active contributors to Otomi."),(0,r.kt)("h2",{id:"code-review"},"Code review"),(0,r.kt)("p",null,"As a community we believe in the value of code review for all contributions.\nCode review increases both the quality and readability of our codebase, which\nin turn produces high quality software."),(0,r.kt)("p",null,"Consequently, as a community we expect that all active participants in the community will also be active reviewers."),(0,r.kt)("h2",{id:"expectations-of-reviewers"},"Expectations of reviewers"),(0,r.kt)("h3",{id:"review-comments"},"Review comments"),(0,r.kt)("p",null,"Because reviewers are often the first points of contact between new members of the community and can significantly impact the first impression of the Otomi community, reviewers are especially important in shaping the Otomi community. Reviewers are highly encouraged to not only abide by the ",(0,r.kt)("a",{parentName:"p",href:"code-of-conduct"},"code of conduct")," but are strongly encouraged to go above and beyond the code of conduct to promote a collaborative, respectful Otomi community."),(0,r.kt)("h3",{id:"review-latency"},"Review latency"),(0,r.kt)("p",null,"Reviewers are expected to respond in a timely fashion to PRs that are assigned to them. Reviewers are expected to respond to an ",(0,r.kt)("em",{parentName:"p"},"active")," PRs with reasonable latency, and if reviewers fail to respond, those PRs may be assigned to other reviewers."),(0,r.kt)("h2",{id:"thank-you"},"Thank you"),(0,r.kt)("p",null,"We want to thank everyone who contributes their time and effort to making Otomi both a successful endeavour as well as a successful community. The strength of our software lies in the combined strengths of each individual community member. Thanks!"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/70b0dc77.2a280f10.js b/assets/js/70b0dc77.07c80da4.js similarity index 97% rename from assets/js/70b0dc77.2a280f10.js rename to assets/js/70b0dc77.07c80da4.js index 6f9e10c2f..9404130e7 100644 --- a/assets/js/70b0dc77.2a280f10.js +++ b/assets/js/70b0dc77.07c80da4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2515],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),d=u(n),g=o,f=d["".concat(l,".").concat(g)]||d[g]||p[g]||i;return n?r.createElement(f,s(s({ref:t},c),{},{components:n})):r.createElement(f,s({ref:t},c))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,s=new Array(i);s[0]=d;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var r=n(7462),o=(n(7294),n(3905));const i={slug:"edge",title:"Otomi at the edge",sidebar_label:"Edge"},s=void 0,a={unversionedId:"use-cases/edge",id:"use-cases/edge",title:"Otomi at the edge",description:"Introduction",source:"@site/product/use-cases/edge.md",sourceDirName:"use-cases",slug:"/use-cases/edge",permalink:"/product/use-cases/edge",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/edge.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"edge",title:"Otomi at the edge",sidebar_label:"Edge"}},l={},u=[{value:"Introduction",id:"introduction",level:2},{value:"How Otomi supports edge computing using Kubernetes",id:"how-otomi-supports-edge-computing-using-kubernetes",level:2}],c={toc:u};function p(e){let{components:t,...i}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"Edge computing is an approach where you run applications as close as possible to its data sources or end users. One of the benefits is improved response times. "),(0,o.kt)("p",null,"However, managing edge applications using Kubernetes comes with challenges, like:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Deploy and update applications consistently accross multiple clusters"),(0,o.kt)("li",{parentName:"ul"},"Manage the run-time specifications for the applications like ingress, certificates, DNS, network policies, etc."),(0,o.kt)("li",{parentName:"ul"},"Lifecycle management of all supporting tools"),(0,o.kt)("li",{parentName:"ul"},"Using managed Kubernetes services in different clouds/infrastructures")),(0,o.kt)("h2",{id:"how-otomi-supports-edge-computing-using-kubernetes"},"How Otomi supports edge computing using Kubernetes"),(0,o.kt)("p",null,"One of the benefits of Otomi is that everything managed by Otomi can be specified in a single values file. This enables you to not only define the applications workloads that need to be running on the cluster, but also all the required tools and configuration to support and secure the workloads."),(0,o.kt)("p",null,"Let's explain this with an example:"),(0,o.kt)("p",null,"Suppose you have 2 application workloads that you would like to run on multiple Kubernetes clusters in multiple geographic regions, using different public cloud providers (AWS, Azure, GCP) and different Kubernetes versions (1.22 and 1.23). Next to the 2 workloads, you also would like to use Istio for mTLS, cert-manager for certificates, ingress/egress network policies for isolation and HTTP response headers. Because you can not afford using L7 load balancers with WAF features in the different clouds, you would like to implement Nginx ingress with Modsecurity and OWASP filtering. The following picture shows the desired situation:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"edge",src:n(2300).Z,width:"1496",height:"1398"})),(0,o.kt)("p",null,"Read ",(0,o.kt)("a",{parentName:"p",href:"../../docs/for-ops/how-to/core-only"},"this")," how-to to learn more about installing Otomi at the edge."))}p.isMDXComponent=!0},2300:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/edge-173d01e1fe3f7ac45484237e916968e3.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2515],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),d=u(n),g=o,f=d["".concat(l,".").concat(g)]||d[g]||p[g]||i;return n?r.createElement(f,s(s({ref:t},c),{},{components:n})):r.createElement(f,s({ref:t},c))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,s=new Array(i);s[0]=d;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a.mdxType="string"==typeof e?e:o,s[1]=a;for(var u=2;u{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var r=n(7462),o=(n(7294),n(3905));const i={slug:"edge",title:"Otomi at the edge",sidebar_label:"Edge"},s=void 0,a={unversionedId:"use-cases/edge",id:"use-cases/edge",title:"Otomi at the edge",description:"Introduction",source:"@site/product/use-cases/edge.md",sourceDirName:"use-cases",slug:"/use-cases/edge",permalink:"/product/use-cases/edge",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/edge.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"edge",title:"Otomi at the edge",sidebar_label:"Edge"}},l={},u=[{value:"Introduction",id:"introduction",level:2},{value:"How Otomi supports edge computing using Kubernetes",id:"how-otomi-supports-edge-computing-using-kubernetes",level:2}],c={toc:u};function p(e){let{components:t,...i}=e;return(0,o.kt)("wrapper",(0,r.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"Edge computing is an approach where you run applications as close as possible to its data sources or end users. One of the benefits is improved response times. "),(0,o.kt)("p",null,"However, managing edge applications using Kubernetes comes with challenges, like:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Deploy and update applications consistently accross multiple clusters"),(0,o.kt)("li",{parentName:"ul"},"Manage the run-time specifications for the applications like ingress, certificates, DNS, network policies, etc."),(0,o.kt)("li",{parentName:"ul"},"Lifecycle management of all supporting tools"),(0,o.kt)("li",{parentName:"ul"},"Using managed Kubernetes services in different clouds/infrastructures")),(0,o.kt)("h2",{id:"how-otomi-supports-edge-computing-using-kubernetes"},"How Otomi supports edge computing using Kubernetes"),(0,o.kt)("p",null,"One of the benefits of Otomi is that everything managed by Otomi can be specified in a single values file. This enables you to not only define the applications workloads that need to be running on the cluster, but also all the required tools and configuration to support and secure the workloads."),(0,o.kt)("p",null,"Let's explain this with an example:"),(0,o.kt)("p",null,"Suppose you have 2 application workloads that you would like to run on multiple Kubernetes clusters in multiple geographic regions, using different public cloud providers (AWS, Azure, GCP) and different Kubernetes versions (1.22 and 1.23). Next to the 2 workloads, you also would like to use Istio for mTLS, cert-manager for certificates, ingress/egress network policies for isolation and HTTP response headers. Because you can not afford using L7 load balancers with WAF features in the different clouds, you would like to implement Nginx ingress with Modsecurity and OWASP filtering. The following picture shows the desired situation:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"edge",src:n(2300).Z,width:"1496",height:"1398"})),(0,o.kt)("p",null,"Read ",(0,o.kt)("a",{parentName:"p",href:"../../docs/for-ops/how-to/core-only"},"this")," how-to to learn more about installing Otomi at the edge."))}p.isMDXComponent=!0},2300:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/edge-173d01e1fe3f7ac45484237e916968e3.png"}}]); \ No newline at end of file diff --git a/assets/js/73148982.73e7c568.js b/assets/js/73148982.a8f9eb15.js similarity index 99% rename from assets/js/73148982.73e7c568.js rename to assets/js/73148982.a8f9eb15.js index 50d941c87..2500b9696 100644 --- a/assets/js/73148982.73e7c568.js +++ b/assets/js/73148982.a8f9eb15.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[1409],{3905:(e,t,i)=>{i.d(t,{Zo:()=>c,kt:()=>m});var o=i(7294);function r(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function n(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,o)}return i}function a(e){for(var t=1;t=0||(r[i]=e[i]);return r}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(r[i]=e[i])}return r}var l=o.createContext({}),d=function(e){var t=o.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):a(a({},t),e)),i},c=function(e){var t=d(e.components);return o.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var i=e.components,r=e.mdxType,n=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),h=d(i),m=r,p=h["".concat(l,".").concat(m)]||h[m]||u[m]||n;return i?o.createElement(p,a(a({ref:t},c),{},{components:i})):o.createElement(p,a({ref:t},c))}));function m(e,t){var i=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var n=i.length,a=new Array(n);a[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var d=2;d{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>n,metadata:()=>s,toc:()=>d});var o=i(7462),r=(i(7294),i(3905));const n={slug:"v1",title:"END USER LICENSE AGREEMENT",sidebar_label:"EULA"},a=void 0,s={unversionedId:"eula/v1",id:"eula/v1",title:"END USER LICENSE AGREEMENT",description:"This EULA is applicable to the usage of Otomi Console and Otomi API.",source:"@site/product/eula/v1.md",sourceDirName:"eula",slug:"/eula/v1",permalink:"/product/eula/v1",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/eula/v1.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"v1",title:"END USER LICENSE AGREEMENT",sidebar_label:"EULA"},sidebar:"mainSidebar",previous:{title:"Serverless",permalink:"/product/use-cases/serverless"}},l={},d=[{value:"1. The Mechanics of the Agreement",id:"1-the-mechanics-of-the-agreement",level:2},{value:"2. License",id:"2-license",level:2},{value:"3. Term",id:"3-term",level:2},{value:"4. Fees and Payment",id:"4-fees-and-payment",level:2},{value:"5. Termination",id:"5-termination",level:2},{value:"6. Representations and Warranties",id:"6-representations-and-warranties",level:2},{value:"7. Confidentiality",id:"7-confidentiality",level:2},{value:"8. End User Information, Feedback, Reservation of Rights, & Review",id:"8-end-user-information-feedback-reservation-of-rights--review",level:2},{value:"9. Review",id:"9-review",level:2},{value:"10. Limitations",id:"10--limitations",level:2},{value:"11. Governing Law and Claims.",id:"11--governing-law-and-claims",level:2},{value:"12. Miscellaneous",id:"12--miscellaneous",level:2},{value:"13. Definitions",id:"13--definitions",level:2}],c={toc:d};function u(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"This EULA is applicable to the usage of Otomi Console and Otomi API."),(0,r.kt)("h1",{id:"otomi-console--api-end-user-license-agreement"},"OTOMI CONSOLE & API END USER LICENSE AGREEMENT"),(0,r.kt)("hr",null),(0,r.kt)("p",null,"PLEASE READ THIS AGREEMENT CAREFULLY BEFORE USING SOFTWARE FROM RED KUBES B.V.. (\u201cRED KUBES\u201d). BY USING RED KUBES SOFTWARE, USER SIGNIFIES ITS ASSENT TO AND ACCEPTANCE OF THIS AGREEMENT AND ACKNOWLEDGES IT HAS READ AND UNDERSTANDS THIS AGREEMENT. IF USER DOES NOT ACCEPT THE TERMS OF THIS AGREEMENT, THEN IT MUST NOT USE RED KUBES SOFTWARE.\nThis Red Kubes End User Agreement is between the User and Red Kubes and addresses relevant considerations that apply to Red Kubes Products, open source software, and our subscription business model. "),(0,r.kt)("h2",{id:"1-the-mechanics-of-the-agreement"},"1. The Mechanics of the Agreement"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Ordering. The Agreement applies to Red Kubes Products for which you acquire the right to access or use, including Subscriptions, access to Red Kubes Online Properties and other Red Kubes offerings. "),(0,r.kt)("li",{parentName:"ol"},"Structure. The Agreement consists of two components: (1) the General Terms and (2) the Product Appendices applicable to Your Products. Certain terms are defined in the General Terms or in the Definitions section at the end of the General Terms. ")),(0,r.kt)("h2",{id:"2-license"},"2. License"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Software License. Subject to your ongoing compliance with all the terms and conditions of this Agreement, Red Kubes hereby grants you a non-exclusive, non-sublicensable, non-transferrable, worldwide, revocable license to download and use the Software, specifically the Community Edition, for your own internal business operation only. "),(0,r.kt)("li",{parentName:"ol"},"License Restrictions. You will not: (a) copy or use the Software in any manner except as expressly permitted in this Agreement; (b) reverse engineer, disassemble, or decompile the Software (except to the extent such restrictions are prohibited by law); (c) alter, modify, enhance or prepare any derivative work from or of the Software; (d) alter or remove any proprietary notices in the Software; or (e) export the Software in violation any export laws or regulations. If you do not comply with the license terms or the foregoing restrictions, Red Kubes may terminate or suspend your license to the Software until you come into compliance with such terms and restrictions.\nThe Software may contain disabling codes that prevent use of the Software outside of the authorized scope and may contain functionality such that the Software reports to Red Kubes certain general metric information about your use of the Software. "),(0,r.kt)("li",{parentName:"ol"},"Third Party Components and Third Party Software. The Software may include third party software components provided under separate license terms (\u201cThird Party Components\u201d), including open source software from the Otomi Project. Nothing in this Agreement limits your rights to obtain and use the Third Party Components under the separate license terms that are applicable to each Third Party Component. However the Software is made available to you only pursuant to this Agreement. In addition, Red Kubes may in its sole discretion, make available other third party software (\u201cThird Party Software\u201d) embedded in, or otherwise provided with, the Software. Third Party Software is expressly excluded from the defined term \u201cSoftware\u201d as used throughout this Agreement. Your use of the Third Party Software is subject to the applicable third party license terms as set forth here, and such Third Party Software is not licensed to you under the terms of this Agreement. If you do not agree to abide by the applicable license terms for the Third Party Software, then you may not access or use the Software or the Third Party Software. You are solely and exclusively responsible for determining if you are permitted to use the Third Party Software and you should address any questions in this regard directly to the relevant Third Party Software licensor. ")),(0,r.kt)("h2",{id:"3-term"},"3. Term"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Agreement Term. The Agreement begins on the Effective Date and continues until it is terminated as set forth below. ")),(0,r.kt)("h2",{id:"4-fees-and-payment"},"4. Fees and Payment"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"The Software is made available to you under this Agreement free of charge. ")),(0,r.kt)("h2",{id:"5-termination"},"5. Termination"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Termination. This Agreement will remain in effect until terminated. You may terminate this Agreement at any time, for any reason or no reason, by ceasing all use of the Software and deleting all copies in your possession or control. Red Kubes may terminate this Agreement at any time, for any reason or no reason, upon notice by any method, including without limitation a post to the web page from which you downloaded the Software or an email sent to an email address you provided when you downloaded the Software. "),(0,r.kt)("li",{parentName:"ol"},"Effect of Termination; Survival. The termination of this Agreement will not terminate or suspend other provisions of the Agreement.")),(0,r.kt)("h2",{id:"6-representations-and-warranties"},"6. Representations and Warranties"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Red Kubes represents and warrants that (a) it has the authority to enter into this Agreement, and (b) to its knowledge, the Software does not, at the time of delivery to you, include malicious mechanisms or code for the purpose of damaging or corrupting the Software.. User represents and warrants that (a) it has the authority to enter into this Agreement, and (b) its use of Red Kubes Products will comply with all applicable laws, and it will not use the Red Kubes Products for any illegal activity. "),(0,r.kt)("li",{parentName:"ol"},"To the maximum extent permitted by applicable law and except as expressly provided in section 6.1, the Red Kubes Products are provided \u2018 as is\u2019 and without any representations or warranties express or implied, and Red Kubes disclaims all such representations and warranties, including the implied warranties of merchantability, non-infringement, and fitness for a particular purpose, and any warranties implied by the course of dealing of usage of trade. Red Kubes and its suppliers do not represent or warrant that the Red Kubes Products will be uninterrupted, secure, error free, accurate or complete or comply with regulatory requirements, or that Red Kubes will correct all errors. In the event of a breach of the warranties set forts in section 6.1., your exclusive remedy, and Red Kubes\u2019 entire liability, will be the re-performance of re-delivery of the deficient Red Kubes Product, or if Red Kubes cannot substantially correct a breach in a commercially reasonable manner, termination of the relevant Red Kubes Product. . "),(0,r.kt)("li",{parentName:"ol"},"The Red Kubes Products have not been tested in all situations under which they may be used. Red Kubes will not be liable for the results obtained through use of the Red Kubes Products and you are solely responsible for determining appropriate uses for the Red Kubes Products and for all results of such use. In particular, Red Kubes Products are not specifically designed, manufactured or intended for use in (a) the design, planning, construction, maintenance, control, or direct operation of nuclear facilities, (b) aircraft control, navigation, or communication systems (c) weapons systems, (d) direct life support systems (e) or other similar hazardous environments. ")),(0,r.kt)("h2",{id:"7-confidentiality"},"7. Confidentiality"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Recipient (a) may not disclose Confidential Information of a Discloser to any third party unless Discloser approves the disclosure in writing or the disclosure is otherwise permitted under this Section 7; (b) will use the same degree of care to protect Confidential Information of Discloser as it uses to protect its own confidential information of a similar nature, but in no event less than reasonable care; and (c) may disclose Confidential Information of the Discloser only to its employees, Affiliates, agents and contractors with a need to know, and to its auditors and legal counsel, in each case, who are under a written obligation (or other professional obligation) to keep such information confidential using standards of confidentiality no less restrictive than those required by this Section 7. These obligations will continue for a period of two (2) years following initial disclosure of the particular Confidential Information. A Recipient may disclose Confidential Information if it is required to do so by applicable law, regulation or court order but, where legally permissible, will provide advance notice to the Discloser to enable the Discloser to seek a protective order or other similar protection if feasible. \u201cRecipient\u201d is the party receiving Confidential Information under this Agreement. \u201cDiscloser\u201d is a party disclosing Confidential Information under this Agreement"),(0,r.kt)("li",{parentName:"ol"},"Information is not Confidential Information, if: (a) the information is or becomes publicly available other than as a result of the Recipient\u2019s breach of this Agreement, (b) the Recipient, at the time of disclosure, knows or possesses the information without obligation of confidentiality or thereafter obtains the information from a third party not under an obligation of confidentiality; (c) the Recipient independently develops the information without use of the Discloser\u2019s Confidential Information, (d) the information is generally known or easily developed by someone with ordinary skills in the business of the Recipient, or (e) the information is licensed under an Open Source License (as defined by the Open Source Initiative (",(0,r.kt)("a",{parentName:"li",href:"https://opensource.org/"},"https://opensource.org/"),")).\n7.3 Confidential Information that is disclosed prior to termination of this Agreement will remain subject to this Agreement for the period set forth above. Upon written request of the Discloser, the Recipient will promptly return or destroy all Confidential Information, except for Confidential Information stored in routine back-up media not accessible during the ordinary course of business. ")),(0,r.kt)("h2",{id:"8-end-user-information-feedback-reservation-of-rights--review"},"8. End User Information, Feedback, Reservation of Rights, & Review"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"End User Information. If you provide End User Information in connection with your use of or access to Red Kubes Products, you agree that, subject to Section 7, Red Kubes, its Affiliates, and Suppliers may use such End User Information in connection with providing the Red Kubes Products. You agree that your provision (and Red Kubes\u2019 use) of End User Information under this Agreement does not require any additional consents or licenses, will be in compliance with applicable law, and will not violate any intellectual property, proprietary, privacy, or other right of any third party. As between Red Kubes and you, you retain all other rights in and to End User Information. "),(0,r.kt)("li",{parentName:"ol"},"Feedback. You may be asked to voluntarily provide Red Kubes with Feedback in connection with Red Kubes Products, but have no obligation to do so. If you choose to do so, Red Kubes may use Feedback for any purpose, including incorporating the Feedback into, or using the Feedback to develop and improve Red Kubes Products and other Red Kubes offerings without attribution or compensation. You grant Red Kubes a perpetual and irrevocable license to use all Feedback for any purpose. You agree to provide Feedback to Red Kubes only in compliance with applicable laws and you represent that you have the authority to provide the Feedback and that Feedback will not include proprietary information of a third party. "),(0,r.kt)("li",{parentName:"ol"},"Reservation of Rights. Red Kubes grants to you only those rights expressly granted in\nthe Agreement with respect to the Red Kubes Products and reserves all other rights in and to the Red Kubes Products (including all intellectual property rights). Red Kubes may collect and use for any purpose aggregate anonymous benchmark data about your use of the Red Kubes Products. Nothing in this Agreement will limit Red Kubes from providing software, materials, or services for itself or other clients, irrespective of the possible similarity of such software, materials or services to those that might be delivered to you. The terms of Section 7 will not prohibit or restrict either party's right to develop, use or market products or services similar to or competitive with the other party; provided, however, that neither party is relieved of its obligations under this Agreement. ")),(0,r.kt)("h2",{id:"9-review"},"9. Review"),(0,r.kt)("p",null,"While this Agreement is in effect and for one year thereafter, Red Kubes or its designee, acting in accordance with Section 7, may inspect your facilities and records to verify your compliance with this Agreement. You agree to (a) respond promptly to requests for information, documents and/or records, (b) grant appropriate access for on-site visits in order to verify your compliance, and (c) reasonably cooperate in connection with any such verification. Red Kubes will provide at least ten (10) days prior written notice for any on-site visits, and will conduct onsite visits during regular business hours in a manner that reasonably minimizes interference with your business. If Red Kubes notifies you of any noncompliance, then you will resolve the non-compliance within fifteen (15) days from the date of notice. "),(0,r.kt)("h2",{id:"10--limitations"},"10. Limitations"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Disclaimer of damages. To the maximum extent permitted by applicable law, neither party, not its Affiliates, will be liable for any incidental, consequential, special, indirect, exemplary or punitive damages, of for any damages for lost or damaged data, lost profits, lost savings of business or service interruption, even if such party was advised of the possibility of such damages, and regardless of the failure of essential purpose of any limited remedy. "),(0,r.kt)("li",{parentName:"ol"},"Limitations of liability. To the maximum extent permitted by applicable law, Red Kubes\u2019 and its Affiliates\u2019 total and aggregate liability with respect to any claim relating to or arising out of this Agreement will not exceed ten euros with respect to the particular Red Kubes Product given rise to liability under the most applicable ordering document during the twelve (12) months immediately preceding the first event giving rise to such claim. This limitation applies regardless of the nature of the claim, whether contract, tort (including negligence), statute or other legal theory. "),(0,r.kt)("li",{parentName:"ol"},"No exclusion or limitation of liability. Notwithstanding any other provision of this Agreement and / or any offer, Red Kubes does not exclude or limit liability for (a) personal injury or death to the extent that such injury or death results from the negligence or willful default of Red Kubes, its agents, Affiliates, or subcontractors; (b) any fraudulent misrepresentation upon which the claiming party can be shown to have relied; or (c) any other liability which is not permissible at law to exclude or limit. ")),(0,r.kt)("h2",{id:"11--governing-law-and-claims"},"11. Governing Law and Claims."),(0,r.kt)("p",null,"The Agreement, and any claim, controversy or dispute related to the Agreement, are governed by and construed in accordance with the Dutch law without giving effect to any conflicts of laws provisions. To the extent permissible, the United Nations Convention on Contracts for the International Sale of Goods will not apply, even if adopted as part of the Dutch law. Any claim, suit, action or proceeding arising out of or relating to this Agreement or its subject matter will be brought exclusively in the courts of the Netherlands and each party irrevocably submits to the exclusive jurisdiction and venue. No claim or action, regardless of form, arising out of this Agreement may be brought by either party more than one (1) year after the party first became aware, or reasonably should have been aware, of the basis for the claim. "),(0,r.kt)("h2",{id:"12--miscellaneous"},"12. Miscellaneous"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Notices. Notices must be in English, in writing, and will be deemed given upon receipt, after being sent using a method that provides for positive confirmation of delivery to the address(es) or email address provided by you, including through an automated receipt or by electronic log. Any notice from you to Red Kubes must include a copy sent to: Red Kubes\u2019 email address ",(0,r.kt)("a",{parentName:"li",href:"mailto:info@redkubes.com."},"info@redkubes.com.")," "),(0,r.kt)("li",{parentName:"ol"},"Assignment. Either party may upon written notice: (a) assign this Agreement to an Affiliate if the Affiliate is able to satisfy the assigning party\u2019s obligations under the Agreement and the assignment will not affect the non-assigning party\u2019s obligations under the Agreement; and (b) assign this Agreement to a successor or acquirer pursuant to a merger or sale of all or substantially all of such party\u2019s assets. Any other assignment will be deemed void and ineffective without the prior written consent of the other party. Subject to the foregoing, this Agreement will be binding upon and will insure to the benefit of the parties and their respective successors and permitted assigns."),(0,r.kt)("li",{parentName:"ol"},"Waiver. A waiver by a party under this Agreement is only valid if in writing and signed by an authorized representative of such party. A delay or failure of a party to exercise any rights under this Agreement will not constitute or be deemed a waiver or forfeiture of such rights. "),(0,r.kt)("li",{parentName:"ol"},"Independent Contractors. The parties are independent contractors and nothing in this Agreement creates an employment, partnership or agency relationship between the parties or any Affiliate. Each party is solely responsible for supervision, control and payment of its personnel. "),(0,r.kt)("li",{parentName:"ol"},"Third Party Beneficiaries. This Agreement is binding on the parties to this Agreement and, other than as expressly provided in the Agreement, nothing in this Agreement grants any other person or entity any right, benefit or remedy. "),(0,r.kt)("li",{parentName:"ol"},"Force Majeure. Neither party is responsible for nonperformance or delay in performance of its obligations due to causes beyond its reasonable control. "),(0,r.kt)("li",{parentName:"ol"},"Complete Agreement and Order of Precedence. The Agreement represents the complete agreement between the parties with respect to its subject matter and supersedes all prior and contemporaneous agreements and proposals, whether written or oral, with respect to such subject matter. Any terms contained in any other documentation that you deliver to Red Kubes, are void and will not become part of the Agreement or otherwise bind the parties. If there is a conflict between the General Terms and the Product Appendices, the General Terms will control unless otherwise expressly provided in the Product Appendices. "),(0,r.kt)("li",{parentName:"ol"},"Counterparts. This Agreement may be executed in counterparts, each of which will be deemed an original and all of which will constitute one and the same document. The parties may exchange signature pages by email or electronic signature process and such signatures will be effective to bind the parties to the Agreement. "),(0,r.kt)("li",{parentName:"ol"},"Severable. If any provision of this Agreement is held by a court of competent jurisdiction to be invalid or unenforceable, the remaining provisions of this Agreement will remain in effect to the greatest extent permitted by law.")),(0,r.kt)("h2",{id:"13--definitions"},"13. Definitions"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\u201cAffiliate\u201d means an entity that owns or controls, is owned or controlled by, or is under common control or ownership with a party, where \u201ccontrol\u201d is the possession, direct or indirect, of the power to direct or cause the direction of the management and policies of an entity, whether through ownership of voting securities, by contract or otherwise. "),(0,r.kt)("li",{parentName:"ol"},"\u201cBusiness Partner\u201d means a cloud provider, distributor, reseller, OEM or other third party authorized to resell or distribute Red Kubes Products. "),(0,r.kt)("li",{parentName:"ol"},"\u201cBusiness Partner order\u201d means an order for a Red Kubes Product placed through a Business Partner. "),(0,r.kt)("li",{parentName:"ol"},"\u201cEnd User\u201d or \u201cyou\u201d means the person or entity acquiring the right to use or access the Red Kubes Products and which is a party to this Agreement. "),(0,r.kt)("li",{parentName:"ol"},"\u201cEnd User Information\u201d means any data, information, software or other materials that you provide to Red Kubes under the Agreement. "),(0,r.kt)("li",{parentName:"ol"},"\u201cConfidential Information\u201d means information disclosed by the Discloser to the Recipient during the term of the Agreement that (i) is marked confidential; (ii) if disclosed orally, is clearly described as confidential at the time of disclosure and is subsequently set forth in writing, marked confidential, and sent to the Recipient within thirty (30) days following the oral disclosure; or (iii) is of a nature that the Recipient knows is confidential to the Discloser or should reasonably be expected to know is confidential. "),(0,r.kt)("li",{parentName:"ol"},"\u201cEffective Date\u201d means earliest of (a) the date of the last signature on this Agreement, (b) your online acceptance of the Agreement, and (c) when you first receive access to a Red Kubes Product. "),(0,r.kt)("li",{parentName:"ol"},"\u201cFeedback\u201d means any ideas, suggestions, proposals or other feedback you may provide regarding Red Kubes Products. "),(0,r.kt)("li",{parentName:"ol"},"\u201cGeneral Terms\u201d means the terms contained in Sections 1 \u2013 13 of this document. "),(0,r.kt)("li",{parentName:"ol"},"\u201cProduct Appendices\u201d means (a) the Red Kubes Product Appendices that are incorporated into an applicable statement of work. "),(0,r.kt)("li",{parentName:"ol"},"\u201cRed Kubes Products\u201d means Software, Services, Subscriptions and other Red Kubes branded offerings made available by Red Kubes. "),(0,r.kt)("li",{parentName:"ol"},"\u201cSoftware\u201d means Red Kubes branded software that is included in Red Kubes Product offerings. "),(0,r.kt)("li",{parentName:"ol"},"\u201cSubscription\u201d means a time bound Red Kubes Services offering, other than Professional Services. "),(0,r.kt)("li",{parentName:"ol"},"\u201cSupplier\u201d means a third party that provides service(s) to Red Kubes in order for Red Kubes to offer Services to its customers and/or Business Partners."),(0,r.kt)("li",{parentName:"ol"},"\u201cYour Products\u201d means the Red Kubes Products that you have purchased, licensed, or otherwise acquired the right to access or use.")))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[1409],{3905:(e,t,i)=>{i.d(t,{Zo:()=>c,kt:()=>m});var o=i(7294);function r(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function n(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,o)}return i}function a(e){for(var t=1;t=0||(r[i]=e[i]);return r}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(r[i]=e[i])}return r}var l=o.createContext({}),d=function(e){var t=o.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):a(a({},t),e)),i},c=function(e){var t=d(e.components);return o.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var i=e.components,r=e.mdxType,n=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),h=d(i),m=r,p=h["".concat(l,".").concat(m)]||h[m]||u[m]||n;return i?o.createElement(p,a(a({ref:t},c),{},{components:i})):o.createElement(p,a({ref:t},c))}));function m(e,t){var i=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var n=i.length,a=new Array(n);a[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var d=2;d{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>n,metadata:()=>s,toc:()=>d});var o=i(7462),r=(i(7294),i(3905));const n={slug:"v1",title:"END USER LICENSE AGREEMENT",sidebar_label:"EULA"},a=void 0,s={unversionedId:"eula/v1",id:"eula/v1",title:"END USER LICENSE AGREEMENT",description:"This EULA is applicable to the usage of Otomi Console and Otomi API.",source:"@site/product/eula/v1.md",sourceDirName:"eula",slug:"/eula/v1",permalink:"/product/eula/v1",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/eula/v1.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"v1",title:"END USER LICENSE AGREEMENT",sidebar_label:"EULA"},sidebar:"mainSidebar",previous:{title:"Serverless",permalink:"/product/use-cases/serverless"}},l={},d=[{value:"1. The Mechanics of the Agreement",id:"1-the-mechanics-of-the-agreement",level:2},{value:"2. License",id:"2-license",level:2},{value:"3. Term",id:"3-term",level:2},{value:"4. Fees and Payment",id:"4-fees-and-payment",level:2},{value:"5. Termination",id:"5-termination",level:2},{value:"6. Representations and Warranties",id:"6-representations-and-warranties",level:2},{value:"7. Confidentiality",id:"7-confidentiality",level:2},{value:"8. End User Information, Feedback, Reservation of Rights, & Review",id:"8-end-user-information-feedback-reservation-of-rights--review",level:2},{value:"9. Review",id:"9-review",level:2},{value:"10. Limitations",id:"10--limitations",level:2},{value:"11. Governing Law and Claims.",id:"11--governing-law-and-claims",level:2},{value:"12. Miscellaneous",id:"12--miscellaneous",level:2},{value:"13. Definitions",id:"13--definitions",level:2}],c={toc:d};function u(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,o.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"This EULA is applicable to the usage of Otomi Console and Otomi API."),(0,r.kt)("h1",{id:"otomi-console--api-end-user-license-agreement"},"OTOMI CONSOLE & API END USER LICENSE AGREEMENT"),(0,r.kt)("hr",null),(0,r.kt)("p",null,"PLEASE READ THIS AGREEMENT CAREFULLY BEFORE USING SOFTWARE FROM RED KUBES B.V.. (\u201cRED KUBES\u201d). BY USING RED KUBES SOFTWARE, USER SIGNIFIES ITS ASSENT TO AND ACCEPTANCE OF THIS AGREEMENT AND ACKNOWLEDGES IT HAS READ AND UNDERSTANDS THIS AGREEMENT. IF USER DOES NOT ACCEPT THE TERMS OF THIS AGREEMENT, THEN IT MUST NOT USE RED KUBES SOFTWARE.\nThis Red Kubes End User Agreement is between the User and Red Kubes and addresses relevant considerations that apply to Red Kubes Products, open source software, and our subscription business model. "),(0,r.kt)("h2",{id:"1-the-mechanics-of-the-agreement"},"1. The Mechanics of the Agreement"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Ordering. The Agreement applies to Red Kubes Products for which you acquire the right to access or use, including Subscriptions, access to Red Kubes Online Properties and other Red Kubes offerings. "),(0,r.kt)("li",{parentName:"ol"},"Structure. The Agreement consists of two components: (1) the General Terms and (2) the Product Appendices applicable to Your Products. Certain terms are defined in the General Terms or in the Definitions section at the end of the General Terms. ")),(0,r.kt)("h2",{id:"2-license"},"2. License"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Software License. Subject to your ongoing compliance with all the terms and conditions of this Agreement, Red Kubes hereby grants you a non-exclusive, non-sublicensable, non-transferrable, worldwide, revocable license to download and use the Software, specifically the Community Edition, for your own internal business operation only. "),(0,r.kt)("li",{parentName:"ol"},"License Restrictions. You will not: (a) copy or use the Software in any manner except as expressly permitted in this Agreement; (b) reverse engineer, disassemble, or decompile the Software (except to the extent such restrictions are prohibited by law); (c) alter, modify, enhance or prepare any derivative work from or of the Software; (d) alter or remove any proprietary notices in the Software; or (e) export the Software in violation any export laws or regulations. If you do not comply with the license terms or the foregoing restrictions, Red Kubes may terminate or suspend your license to the Software until you come into compliance with such terms and restrictions.\nThe Software may contain disabling codes that prevent use of the Software outside of the authorized scope and may contain functionality such that the Software reports to Red Kubes certain general metric information about your use of the Software. "),(0,r.kt)("li",{parentName:"ol"},"Third Party Components and Third Party Software. The Software may include third party software components provided under separate license terms (\u201cThird Party Components\u201d), including open source software from the Otomi Project. Nothing in this Agreement limits your rights to obtain and use the Third Party Components under the separate license terms that are applicable to each Third Party Component. However the Software is made available to you only pursuant to this Agreement. In addition, Red Kubes may in its sole discretion, make available other third party software (\u201cThird Party Software\u201d) embedded in, or otherwise provided with, the Software. Third Party Software is expressly excluded from the defined term \u201cSoftware\u201d as used throughout this Agreement. Your use of the Third Party Software is subject to the applicable third party license terms as set forth here, and such Third Party Software is not licensed to you under the terms of this Agreement. If you do not agree to abide by the applicable license terms for the Third Party Software, then you may not access or use the Software or the Third Party Software. You are solely and exclusively responsible for determining if you are permitted to use the Third Party Software and you should address any questions in this regard directly to the relevant Third Party Software licensor. ")),(0,r.kt)("h2",{id:"3-term"},"3. Term"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Agreement Term. The Agreement begins on the Effective Date and continues until it is terminated as set forth below. ")),(0,r.kt)("h2",{id:"4-fees-and-payment"},"4. Fees and Payment"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"The Software is made available to you under this Agreement free of charge. ")),(0,r.kt)("h2",{id:"5-termination"},"5. Termination"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Termination. This Agreement will remain in effect until terminated. You may terminate this Agreement at any time, for any reason or no reason, by ceasing all use of the Software and deleting all copies in your possession or control. Red Kubes may terminate this Agreement at any time, for any reason or no reason, upon notice by any method, including without limitation a post to the web page from which you downloaded the Software or an email sent to an email address you provided when you downloaded the Software. "),(0,r.kt)("li",{parentName:"ol"},"Effect of Termination; Survival. The termination of this Agreement will not terminate or suspend other provisions of the Agreement.")),(0,r.kt)("h2",{id:"6-representations-and-warranties"},"6. Representations and Warranties"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Red Kubes represents and warrants that (a) it has the authority to enter into this Agreement, and (b) to its knowledge, the Software does not, at the time of delivery to you, include malicious mechanisms or code for the purpose of damaging or corrupting the Software.. User represents and warrants that (a) it has the authority to enter into this Agreement, and (b) its use of Red Kubes Products will comply with all applicable laws, and it will not use the Red Kubes Products for any illegal activity. "),(0,r.kt)("li",{parentName:"ol"},"To the maximum extent permitted by applicable law and except as expressly provided in section 6.1, the Red Kubes Products are provided \u2018 as is\u2019 and without any representations or warranties express or implied, and Red Kubes disclaims all such representations and warranties, including the implied warranties of merchantability, non-infringement, and fitness for a particular purpose, and any warranties implied by the course of dealing of usage of trade. Red Kubes and its suppliers do not represent or warrant that the Red Kubes Products will be uninterrupted, secure, error free, accurate or complete or comply with regulatory requirements, or that Red Kubes will correct all errors. In the event of a breach of the warranties set forts in section 6.1., your exclusive remedy, and Red Kubes\u2019 entire liability, will be the re-performance of re-delivery of the deficient Red Kubes Product, or if Red Kubes cannot substantially correct a breach in a commercially reasonable manner, termination of the relevant Red Kubes Product. . "),(0,r.kt)("li",{parentName:"ol"},"The Red Kubes Products have not been tested in all situations under which they may be used. Red Kubes will not be liable for the results obtained through use of the Red Kubes Products and you are solely responsible for determining appropriate uses for the Red Kubes Products and for all results of such use. In particular, Red Kubes Products are not specifically designed, manufactured or intended for use in (a) the design, planning, construction, maintenance, control, or direct operation of nuclear facilities, (b) aircraft control, navigation, or communication systems (c) weapons systems, (d) direct life support systems (e) or other similar hazardous environments. ")),(0,r.kt)("h2",{id:"7-confidentiality"},"7. Confidentiality"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Recipient (a) may not disclose Confidential Information of a Discloser to any third party unless Discloser approves the disclosure in writing or the disclosure is otherwise permitted under this Section 7; (b) will use the same degree of care to protect Confidential Information of Discloser as it uses to protect its own confidential information of a similar nature, but in no event less than reasonable care; and (c) may disclose Confidential Information of the Discloser only to its employees, Affiliates, agents and contractors with a need to know, and to its auditors and legal counsel, in each case, who are under a written obligation (or other professional obligation) to keep such information confidential using standards of confidentiality no less restrictive than those required by this Section 7. These obligations will continue for a period of two (2) years following initial disclosure of the particular Confidential Information. A Recipient may disclose Confidential Information if it is required to do so by applicable law, regulation or court order but, where legally permissible, will provide advance notice to the Discloser to enable the Discloser to seek a protective order or other similar protection if feasible. \u201cRecipient\u201d is the party receiving Confidential Information under this Agreement. \u201cDiscloser\u201d is a party disclosing Confidential Information under this Agreement"),(0,r.kt)("li",{parentName:"ol"},"Information is not Confidential Information, if: (a) the information is or becomes publicly available other than as a result of the Recipient\u2019s breach of this Agreement, (b) the Recipient, at the time of disclosure, knows or possesses the information without obligation of confidentiality or thereafter obtains the information from a third party not under an obligation of confidentiality; (c) the Recipient independently develops the information without use of the Discloser\u2019s Confidential Information, (d) the information is generally known or easily developed by someone with ordinary skills in the business of the Recipient, or (e) the information is licensed under an Open Source License (as defined by the Open Source Initiative (",(0,r.kt)("a",{parentName:"li",href:"https://opensource.org/"},"https://opensource.org/"),")).\n7.3 Confidential Information that is disclosed prior to termination of this Agreement will remain subject to this Agreement for the period set forth above. Upon written request of the Discloser, the Recipient will promptly return or destroy all Confidential Information, except for Confidential Information stored in routine back-up media not accessible during the ordinary course of business. ")),(0,r.kt)("h2",{id:"8-end-user-information-feedback-reservation-of-rights--review"},"8. End User Information, Feedback, Reservation of Rights, & Review"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"End User Information. If you provide End User Information in connection with your use of or access to Red Kubes Products, you agree that, subject to Section 7, Red Kubes, its Affiliates, and Suppliers may use such End User Information in connection with providing the Red Kubes Products. You agree that your provision (and Red Kubes\u2019 use) of End User Information under this Agreement does not require any additional consents or licenses, will be in compliance with applicable law, and will not violate any intellectual property, proprietary, privacy, or other right of any third party. As between Red Kubes and you, you retain all other rights in and to End User Information. "),(0,r.kt)("li",{parentName:"ol"},"Feedback. You may be asked to voluntarily provide Red Kubes with Feedback in connection with Red Kubes Products, but have no obligation to do so. If you choose to do so, Red Kubes may use Feedback for any purpose, including incorporating the Feedback into, or using the Feedback to develop and improve Red Kubes Products and other Red Kubes offerings without attribution or compensation. You grant Red Kubes a perpetual and irrevocable license to use all Feedback for any purpose. You agree to provide Feedback to Red Kubes only in compliance with applicable laws and you represent that you have the authority to provide the Feedback and that Feedback will not include proprietary information of a third party. "),(0,r.kt)("li",{parentName:"ol"},"Reservation of Rights. Red Kubes grants to you only those rights expressly granted in\nthe Agreement with respect to the Red Kubes Products and reserves all other rights in and to the Red Kubes Products (including all intellectual property rights). Red Kubes may collect and use for any purpose aggregate anonymous benchmark data about your use of the Red Kubes Products. Nothing in this Agreement will limit Red Kubes from providing software, materials, or services for itself or other clients, irrespective of the possible similarity of such software, materials or services to those that might be delivered to you. The terms of Section 7 will not prohibit or restrict either party's right to develop, use or market products or services similar to or competitive with the other party; provided, however, that neither party is relieved of its obligations under this Agreement. ")),(0,r.kt)("h2",{id:"9-review"},"9. Review"),(0,r.kt)("p",null,"While this Agreement is in effect and for one year thereafter, Red Kubes or its designee, acting in accordance with Section 7, may inspect your facilities and records to verify your compliance with this Agreement. You agree to (a) respond promptly to requests for information, documents and/or records, (b) grant appropriate access for on-site visits in order to verify your compliance, and (c) reasonably cooperate in connection with any such verification. Red Kubes will provide at least ten (10) days prior written notice for any on-site visits, and will conduct onsite visits during regular business hours in a manner that reasonably minimizes interference with your business. If Red Kubes notifies you of any noncompliance, then you will resolve the non-compliance within fifteen (15) days from the date of notice. "),(0,r.kt)("h2",{id:"10--limitations"},"10. Limitations"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Disclaimer of damages. To the maximum extent permitted by applicable law, neither party, not its Affiliates, will be liable for any incidental, consequential, special, indirect, exemplary or punitive damages, of for any damages for lost or damaged data, lost profits, lost savings of business or service interruption, even if such party was advised of the possibility of such damages, and regardless of the failure of essential purpose of any limited remedy. "),(0,r.kt)("li",{parentName:"ol"},"Limitations of liability. To the maximum extent permitted by applicable law, Red Kubes\u2019 and its Affiliates\u2019 total and aggregate liability with respect to any claim relating to or arising out of this Agreement will not exceed ten euros with respect to the particular Red Kubes Product given rise to liability under the most applicable ordering document during the twelve (12) months immediately preceding the first event giving rise to such claim. This limitation applies regardless of the nature of the claim, whether contract, tort (including negligence), statute or other legal theory. "),(0,r.kt)("li",{parentName:"ol"},"No exclusion or limitation of liability. Notwithstanding any other provision of this Agreement and / or any offer, Red Kubes does not exclude or limit liability for (a) personal injury or death to the extent that such injury or death results from the negligence or willful default of Red Kubes, its agents, Affiliates, or subcontractors; (b) any fraudulent misrepresentation upon which the claiming party can be shown to have relied; or (c) any other liability which is not permissible at law to exclude or limit. ")),(0,r.kt)("h2",{id:"11--governing-law-and-claims"},"11. Governing Law and Claims."),(0,r.kt)("p",null,"The Agreement, and any claim, controversy or dispute related to the Agreement, are governed by and construed in accordance with the Dutch law without giving effect to any conflicts of laws provisions. To the extent permissible, the United Nations Convention on Contracts for the International Sale of Goods will not apply, even if adopted as part of the Dutch law. Any claim, suit, action or proceeding arising out of or relating to this Agreement or its subject matter will be brought exclusively in the courts of the Netherlands and each party irrevocably submits to the exclusive jurisdiction and venue. No claim or action, regardless of form, arising out of this Agreement may be brought by either party more than one (1) year after the party first became aware, or reasonably should have been aware, of the basis for the claim. "),(0,r.kt)("h2",{id:"12--miscellaneous"},"12. Miscellaneous"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Notices. Notices must be in English, in writing, and will be deemed given upon receipt, after being sent using a method that provides for positive confirmation of delivery to the address(es) or email address provided by you, including through an automated receipt or by electronic log. Any notice from you to Red Kubes must include a copy sent to: Red Kubes\u2019 email address ",(0,r.kt)("a",{parentName:"li",href:"mailto:info@redkubes.com."},"info@redkubes.com.")," "),(0,r.kt)("li",{parentName:"ol"},"Assignment. Either party may upon written notice: (a) assign this Agreement to an Affiliate if the Affiliate is able to satisfy the assigning party\u2019s obligations under the Agreement and the assignment will not affect the non-assigning party\u2019s obligations under the Agreement; and (b) assign this Agreement to a successor or acquirer pursuant to a merger or sale of all or substantially all of such party\u2019s assets. Any other assignment will be deemed void and ineffective without the prior written consent of the other party. Subject to the foregoing, this Agreement will be binding upon and will insure to the benefit of the parties and their respective successors and permitted assigns."),(0,r.kt)("li",{parentName:"ol"},"Waiver. A waiver by a party under this Agreement is only valid if in writing and signed by an authorized representative of such party. A delay or failure of a party to exercise any rights under this Agreement will not constitute or be deemed a waiver or forfeiture of such rights. "),(0,r.kt)("li",{parentName:"ol"},"Independent Contractors. The parties are independent contractors and nothing in this Agreement creates an employment, partnership or agency relationship between the parties or any Affiliate. Each party is solely responsible for supervision, control and payment of its personnel. "),(0,r.kt)("li",{parentName:"ol"},"Third Party Beneficiaries. This Agreement is binding on the parties to this Agreement and, other than as expressly provided in the Agreement, nothing in this Agreement grants any other person or entity any right, benefit or remedy. "),(0,r.kt)("li",{parentName:"ol"},"Force Majeure. Neither party is responsible for nonperformance or delay in performance of its obligations due to causes beyond its reasonable control. "),(0,r.kt)("li",{parentName:"ol"},"Complete Agreement and Order of Precedence. The Agreement represents the complete agreement between the parties with respect to its subject matter and supersedes all prior and contemporaneous agreements and proposals, whether written or oral, with respect to such subject matter. Any terms contained in any other documentation that you deliver to Red Kubes, are void and will not become part of the Agreement or otherwise bind the parties. If there is a conflict between the General Terms and the Product Appendices, the General Terms will control unless otherwise expressly provided in the Product Appendices. "),(0,r.kt)("li",{parentName:"ol"},"Counterparts. This Agreement may be executed in counterparts, each of which will be deemed an original and all of which will constitute one and the same document. The parties may exchange signature pages by email or electronic signature process and such signatures will be effective to bind the parties to the Agreement. "),(0,r.kt)("li",{parentName:"ol"},"Severable. If any provision of this Agreement is held by a court of competent jurisdiction to be invalid or unenforceable, the remaining provisions of this Agreement will remain in effect to the greatest extent permitted by law.")),(0,r.kt)("h2",{id:"13--definitions"},"13. Definitions"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\u201cAffiliate\u201d means an entity that owns or controls, is owned or controlled by, or is under common control or ownership with a party, where \u201ccontrol\u201d is the possession, direct or indirect, of the power to direct or cause the direction of the management and policies of an entity, whether through ownership of voting securities, by contract or otherwise. "),(0,r.kt)("li",{parentName:"ol"},"\u201cBusiness Partner\u201d means a cloud provider, distributor, reseller, OEM or other third party authorized to resell or distribute Red Kubes Products. "),(0,r.kt)("li",{parentName:"ol"},"\u201cBusiness Partner order\u201d means an order for a Red Kubes Product placed through a Business Partner. "),(0,r.kt)("li",{parentName:"ol"},"\u201cEnd User\u201d or \u201cyou\u201d means the person or entity acquiring the right to use or access the Red Kubes Products and which is a party to this Agreement. "),(0,r.kt)("li",{parentName:"ol"},"\u201cEnd User Information\u201d means any data, information, software or other materials that you provide to Red Kubes under the Agreement. "),(0,r.kt)("li",{parentName:"ol"},"\u201cConfidential Information\u201d means information disclosed by the Discloser to the Recipient during the term of the Agreement that (i) is marked confidential; (ii) if disclosed orally, is clearly described as confidential at the time of disclosure and is subsequently set forth in writing, marked confidential, and sent to the Recipient within thirty (30) days following the oral disclosure; or (iii) is of a nature that the Recipient knows is confidential to the Discloser or should reasonably be expected to know is confidential. "),(0,r.kt)("li",{parentName:"ol"},"\u201cEffective Date\u201d means earliest of (a) the date of the last signature on this Agreement, (b) your online acceptance of the Agreement, and (c) when you first receive access to a Red Kubes Product. "),(0,r.kt)("li",{parentName:"ol"},"\u201cFeedback\u201d means any ideas, suggestions, proposals or other feedback you may provide regarding Red Kubes Products. "),(0,r.kt)("li",{parentName:"ol"},"\u201cGeneral Terms\u201d means the terms contained in Sections 1 \u2013 13 of this document. "),(0,r.kt)("li",{parentName:"ol"},"\u201cProduct Appendices\u201d means (a) the Red Kubes Product Appendices that are incorporated into an applicable statement of work. "),(0,r.kt)("li",{parentName:"ol"},"\u201cRed Kubes Products\u201d means Software, Services, Subscriptions and other Red Kubes branded offerings made available by Red Kubes. "),(0,r.kt)("li",{parentName:"ol"},"\u201cSoftware\u201d means Red Kubes branded software that is included in Red Kubes Product offerings. "),(0,r.kt)("li",{parentName:"ol"},"\u201cSubscription\u201d means a time bound Red Kubes Services offering, other than Professional Services. "),(0,r.kt)("li",{parentName:"ol"},"\u201cSupplier\u201d means a third party that provides service(s) to Red Kubes in order for Red Kubes to offer Services to its customers and/or Business Partners."),(0,r.kt)("li",{parentName:"ol"},"\u201cYour Products\u201d means the Red Kubes Products that you have purchased, licensed, or otherwise acquired the right to access or use.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.39c3c5ac.js b/assets/js/935f2afb.39c3c5ac.js new file mode 100644 index 000000000..dd7e9b5bb --- /dev/null +++ b/assets/js/935f2afb.39c3c5ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"mainSidebar":[{"type":"category","label":"Getting Started","items":[{"type":"link","label":"Prerequisites","href":"/docs/get-started/prerequisites","docId":"get-started/prerequisites"},{"type":"link","label":"Installation","href":"/docs/get-started/installation","docId":"get-started/installation"},{"type":"link","label":"Activation","href":"/docs/get-started/activation","docId":"get-started/activation"},{"type":"link","label":"Get Started Labs","href":"/docs/for-devs/get-started/overview","docId":"for-devs/get-started/overview"}],"collapsed":true,"collapsible":true},{"type":"category","label":"For Ops","items":[{"type":"category","label":"Otomi Console","items":[{"type":"link","label":"Overview","href":"/docs/for-ops/console/overview","docId":"for-ops/console/overview"},{"type":"link","label":"Apps","href":"/docs/for-ops/console/apps","docId":"for-ops/console/apps"},{"type":"link","label":"Shortcuts","href":"/docs/for-ops/console/shortcuts","docId":"for-ops/console/shortcuts"},{"type":"link","label":"Clusters","href":"/docs/for-ops/console/clusters","docId":"for-ops/console/clusters"},{"type":"link","label":"Policies","href":"/docs/for-ops/console/policies","docId":"for-ops/console/policies"},{"type":"link","label":"Teams","href":"/docs/for-ops/console/teams","docId":"for-ops/console/teams"},{"type":"link","label":"Projects","href":"/docs/for-ops/console/projects","docId":"for-ops/console/projects"},{"type":"link","label":"Builds","href":"/docs/for-ops/console/builds","docId":"for-ops/console/builds"},{"type":"link","label":"Secrets","href":"/docs/for-ops/console/secrets","docId":"for-ops/console/secrets"},{"type":"link","label":"Workloads","href":"/docs/for-ops/console/workloads","docId":"for-ops/console/workloads"},{"type":"link","label":"Services","href":"/docs/for-ops/console/services","docId":"for-ops/console/services"},{"type":"link","label":"Backups","href":"/docs/for-ops/console/backups","docId":"for-ops/console/backups"},{"type":"link","label":"Shell","href":"/docs/for-ops/console/shell","docId":"for-ops/console/shell"},{"type":"category","label":"Settings","items":[{"type":"link","label":"Cluster","href":"/docs/for-ops/console/settings/cluster","docId":"for-ops/console/settings/cluster"},{"type":"link","label":"Otomi","href":"/docs/for-ops/console/settings/otomi","docId":"for-ops/console/settings/otomi"},{"type":"link","label":"Key Management","href":"/docs/for-ops/console/settings/key-management","docId":"for-ops/console/settings/key-management"},{"type":"link","label":"Alerts","href":"/docs/for-ops/console/settings/alerts","docId":"for-ops/console/settings/alerts"},{"type":"link","label":"Co-monitoring","href":"/docs/for-ops/console/settings/co-monitoring","docId":"for-ops/console/settings/co-monitoring"},{"type":"link","label":"Azure","href":"/docs/for-ops/console/settings/azure","docId":"for-ops/console/settings/azure"},{"type":"link","label":"DNS","href":"/docs/for-ops/console/settings/dns","docId":"for-ops/console/settings/dns"},{"type":"link","label":"Ingress","href":"/docs/for-ops/console/settings/ingress","docId":"for-ops/console/settings/ingress"},{"type":"link","label":"OIDC","href":"/docs/for-ops/console/settings/oidc","docId":"for-ops/console/settings/oidc"},{"type":"link","label":"SMTP","href":"/docs/for-ops/console/settings/smtp","docId":"for-ops/console/settings/smtp"},{"type":"link","label":"Backup","href":"/docs/for-ops/console/settings/backup","docId":"for-ops/console/settings/backup"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"How To","items":[{"type":"link","label":"Use private ingress class","href":"/docs/for-ops/how-to/ingress-classes","docId":"for-ops/how-to/ingress-classes"},{"type":"link","label":"Use Team Admin","href":"/docs/for-ops/how-to/use-team-admin","docId":"for-ops/how-to/use-team-admin"},{"type":"link","label":"Use Core only","href":"/docs/for-ops/how-to/core-only","docId":"for-ops/how-to/core-only"},{"type":"link","label":"Install with DNS","href":"/docs/for-ops/how-to/install-with-dns","docId":"for-ops/how-to/install-with-dns"},{"type":"link","label":"Backups","href":"/docs/for-ops/how-to/backups","docId":"for-ops/how-to/create-and-restore-backups"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Otomi CLI","items":[{"type":"link","label":"Installation","href":"/docs/for-ops/cli/installation","docId":"for-ops/cli/installation"},{"type":"link","label":"Using Otomi CLI","href":"/docs/for-ops/cli/deploying","docId":"for-ops/cli/deploying"},{"type":"link","label":"Known issues","href":"/docs/for-ops/cli/known-issues","docId":"for-ops/cli/known-issues"},{"type":"category","label":"CLI Commands","items":[{"type":"link","label":"otomi apply","href":"/docs/for-ops/cli/apply","docId":"for-ops/cli/apply"},{"type":"link","label":"otomi bash","href":"/docs/for-ops/cli/bash","docId":"for-ops/cli/bash"},{"type":"link","label":"otomi bootstrap","href":"/docs/for-ops/cli/bootstrap","docId":"for-ops/cli/bootstrap"},{"type":"link","label":"otomi check-policies","href":"/docs/for-ops/cli/check-policies","docId":"for-ops/cli/check-policies"},{"type":"link","label":"otomi commit","href":"/docs/for-ops/cli/commit","docId":"for-ops/cli/commit"},{"type":"link","label":"otomi decrypt","href":"/docs/for-ops/cli/decrypt","docId":"for-ops/cli/decrypt"},{"type":"link","label":"otomi destroy","href":"/docs/for-ops/cli/destroy","docId":"for-ops/cli/destroy"},{"type":"link","label":"otomi diff","href":"/docs/for-ops/cli/diff","docId":"for-ops/cli/diff"},{"type":"link","label":"otomi encrypt","href":"/docs/for-ops/cli/encrypt","docId":"for-ops/cli/encrypt"},{"type":"link","label":"otomi lint","href":"/docs/for-ops/cli/lint","docId":"for-ops/cli/lint"},{"type":"link","label":"otomi pull","href":"/docs/for-ops/cli/pull","docId":"for-ops/cli/pull"},{"type":"link","label":"otomi rotate-keys","href":"/docs/for-ops/cli/rotate-keys","docId":"for-ops/cli/rotate-keys"},{"type":"link","label":"otomi status","href":"/docs/for-ops/cli/status","docId":"for-ops/cli/status"},{"type":"link","label":"otomi sync","href":"/docs/for-ops/cli/sync","docId":"for-ops/cli/sync"},{"type":"link","label":"otomi template","href":"/docs/for-ops/cli/template","docId":"for-ops/cli/template"},{"type":"link","label":"otomi test","href":"/docs/for-ops/cli/test","docId":"for-ops/cli/test"},{"type":"link","label":"otomi validate-templates","href":"/docs/for-ops/cli/validate-templates","docId":"for-ops/cli/validate-templates"},{"type":"link","label":"otomi validate-values","href":"/docs/for-ops/cli/validate-values","docId":"for-ops/cli/validate-values"},{"type":"link","label":"otomi values","href":"/docs/for-ops/cli/values","docId":"for-ops/cli/values"},{"type":"link","label":"otomi x","href":"/docs/for-ops/cli/x","docId":"for-ops/cli/x"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"SRE","items":[{"type":"link","label":"Overview","href":"/docs/for-ops/sre/overview","docId":"for-ops/sre/overview"},{"type":"link","label":"Daily Routine","href":"/docs/for-ops/sre/daily","docId":"for-ops/sre/daily"},{"type":"link","label":"Upgrades","href":"/docs/for-ops/sre/upgrades","docId":"for-ops/sre/upgrades"},{"type":"link","label":"Troubleshooting","href":"/docs/for-ops/sre/troubleshooting","docId":"for-ops/sre/troubleshooting"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"For Devs","items":[{"type":"category","label":"Otomi Console","items":[{"type":"link","label":"Apps","href":"/docs/for-devs/console/apps","docId":"for-devs/console/apps"},{"type":"link","label":"Shortcuts","href":"/docs/for-devs/console/shortcuts","docId":"for-devs/console/shortcuts"},{"type":"link","label":"Projects","href":"/docs/for-devs/console/projects","docId":"for-devs/console/projects"},{"type":"link","label":"Builds","href":"/docs/for-devs/console/builds","docId":"for-devs/console/builds"},{"type":"link","label":"Workloads","href":"/docs/for-devs/console/workloads","docId":"for-devs/console/workloads"},{"type":"link","label":"Services","href":"/docs/for-devs/console/services","docId":"for-devs/console/services"},{"type":"link","label":"Secrets","href":"/docs/for-devs/console/secrets","docId":"for-devs/console/secrets"},{"type":"link","label":"Shell","href":"/docs/for-devs/console/shell","docId":"for-devs/console/shell"},{"type":"link","label":"Deploy Changes","href":"/docs/for-devs/console/deploy-changes","docId":"for-devs/console/deploy-changes"},{"type":"link","label":"Settings","href":"/docs/for-devs/console/settings","docId":"for-devs/console/settings"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Get Started With Otomi","items":[{"type":"link","label":"Get Started Labs","href":"/docs/for-devs/get-started/overview","docId":"for-devs/get-started/overview"},{"type":"link","label":"Prerequisites","href":"/docs/for-devs/get-started/lab-1","docId":"for-devs/get-started/lab-1"},{"type":"link","label":"Access Console","href":"/docs/for-devs/get-started/lab-2","docId":"for-devs/get-started/lab-2"},{"type":"link","label":"Create repo","href":"/docs/for-devs/get-started/lab-3","docId":"for-devs/get-started/lab-3"},{"type":"link","label":"Create a custom CI pipeline","href":"/docs/for-devs/get-started/lab-4","docId":"for-devs/get-started/lab-4"},{"type":"link","label":"Push images","href":"/docs/for-devs/get-started/lab-5","docId":"for-devs/get-started/lab-5"},{"type":"link","label":"Build images with Otomi","href":"/docs/for-devs/get-started/lab-6","docId":"for-devs/get-started/lab-6"},{"type":"link","label":"Trigger builds","href":"/docs/for-devs/get-started/lab-26","docId":"for-devs/get-started/lab-26"},{"type":"link","label":"Scan images","href":"/docs/for-devs/get-started/lab-7","docId":"for-devs/get-started/lab-7"},{"type":"link","label":"Create secrets","href":"/docs/for-devs/get-started/lab-8","docId":"for-devs/get-started/lab-8"},{"type":"link","label":"Using Argo CD","href":"/docs/for-devs/get-started/lab-10","docId":"for-devs/get-started/lab-10"},{"type":"link","label":"Use auto image updater","href":"/docs/for-devs/get-started/lab-11","docId":"for-devs/get-started/lab-11"},{"type":"link","label":"Create BYO workload","href":"/docs/for-devs/get-started/lab-12","docId":"for-devs/get-started/lab-12"},{"type":"link","label":"Create Otomi workload","href":"/docs/for-devs/get-started/lab-13","docId":"for-devs/get-started/lab-13"},{"type":"link","label":"Create a database","href":"/docs/for-devs/get-started/lab-24","docId":"for-devs/get-started/lab-24"},{"type":"link","label":"Check policy compliance","href":"/docs/for-devs/get-started/lab-15","docId":"for-devs/get-started/lab-15"},{"type":"link","label":"Scan running containers","href":"/docs/for-devs/get-started/lab-17","docId":"for-devs/get-started/lab-17"},{"type":"link","label":"Expose services","href":"/docs/for-devs/get-started/lab-18","docId":"for-devs/get-started/lab-18"},{"type":"link","label":"Configure network policies","href":"/docs/for-devs/get-started/lab-19","docId":"for-devs/get-started/lab-19"},{"type":"link","label":"View container logs","href":"/docs/for-devs/get-started/lab-20","docId":"for-devs/get-started/lab-20"},{"type":"link","label":"View container metrics","href":"/docs/for-devs/get-started/lab-21","docId":"for-devs/get-started/lab-21"},{"type":"link","label":"Using custom metrics","href":"/docs/for-devs/get-started/lab-22","docId":"for-devs/get-started/lab-22"},{"type":"link","label":"Monitor services","href":"/docs/for-devs/get-started/lab-23","docId":"for-devs/get-started/lab-23"},{"type":"link","label":"Monitor databases","href":"/docs/for-devs/get-started/lab-25","docId":"for-devs/get-started/lab-25"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Otomi Applications","items":[{"type":"link","label":"Alertmanager","href":"/docs/apps/alertmanager","docId":"apps/alertmanager"},{"type":"link","label":"ArgoCD","href":"/docs/apps/argocd","docId":"apps/argocd"},{"type":"link","label":"Cert-Manager","href":"/docs/apps/certmanager","docId":"apps/certmanager"},{"type":"link","label":"Drone","href":"/docs/apps/drone","docId":"apps/drone"},{"type":"link","label":"ExternalDNS","href":"/docs/apps/external-dns","docId":"apps/external-dns"},{"type":"link","label":"Gatekeeper","href":"/docs/apps/gatekeeper","docId":"apps/gatekeeper"},{"type":"link","label":"Gitea","href":"/docs/apps/gitea","docId":"apps/gitea"},{"type":"link","label":"Grafana","href":"/docs/apps/grafana","docId":"apps/grafana"},{"type":"link","label":"Harbor","href":"/docs/apps/harbor","docId":"apps/harbor"},{"type":"link","label":"Ingress-nginx","href":"/docs/apps/ingress-nginx","docId":"apps/ingress-nginx"},{"type":"link","label":"Istio","href":"/docs/apps/istio","docId":"apps/istio"},{"type":"link","label":"Jaeger","href":"/docs/apps/jaeger","docId":"apps/jaeger"},{"type":"link","label":"Keycloak","href":"/docs/apps/keycloak","docId":"apps/keycloak"},{"type":"link","label":"Knative","href":"/docs/apps/knative","docId":"apps/knative"},{"type":"link","label":"Kubeapps","href":"/docs/apps/kubeapps","docId":"apps/kubeapps"},{"type":"link","label":"Kubeclarity","href":"/docs/apps/kubeclarity","docId":"apps/kubeclarity"},{"type":"link","label":"Loki","href":"/docs/apps/loki","docId":"apps/loki"},{"type":"link","label":"Minio","href":"/docs/apps/minio","docId":"apps/minio"},{"type":"link","label":"Prometheus","href":"/docs/apps/prometheus","docId":"apps/prometheus"},{"type":"link","label":"Thanos","href":"/docs/apps/thanos","docId":"apps/thanos"},{"type":"link","label":"Trivy Operator","href":"/docs/apps/trivy","docId":"apps/trivy"},{"type":"link","label":"Tekton","href":"/docs/apps/tekton","docId":"apps/tekton"},{"type":"link","label":"Hashicorp Vault","href":"/docs/apps/vault","docId":"apps/vault"},{"type":"link","label":"Velero","href":"/docs/apps/velero","docId":"apps/velero"}],"collapsed":true,"collapsible":true}]},"docs":{"apps/alertmanager":{"id":"apps/alertmanager","title":"Alertmanager","description":"Alertmanager handles alerts sent by client applications such as the Prometheus server. It takes care of de-duplicating, grouping, and routing them to the correct receiver integration such as email, Slack, MS Teams, or OpsGenie. It also takes care of silencing and inhibition of alerts.","sidebar":"mainSidebar"},"apps/argocd":{"id":"apps/argocd","title":"ArgoCD","description":"ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes. ArgoCD is configured by Otomi to use the SSO provided by keycloak, and maps otomi groups to ArgoCD roles. The otomi-admin role is made super admin within ArgoCD. The team-admin role has access to ArgoCD and is admin of all team projects. Members of team roles are only allowed to administer their own projects. All Teams will automatically get access to a Git repo, and ArgoCD is configured to listen to this repo. All a team has to do is to fill their repo with intended state, commit, and automation takes care of the rest.","sidebar":"mainSidebar"},"apps/certmanager":{"id":"apps/certmanager","title":"CertManager","description":"Cert-Manager is used by Otomi to automatically create and rotate wildcard TLS certificates for service endpoints. You may bring your own CA, or let Otomi create one for you. If you bring your own trusted wildcard certificate, then cert-manager will not manage this certificate.","sidebar":"mainSidebar"},"apps/drone":{"id":"apps/drone","title":"Drone","description":"Otomi uses Drone to deploy changes from the values repo. As such, it is installed and configured by default. When no source control is configured, Otomi will deploy Gitea as Drone\'s git hosting dependency.","sidebar":"mainSidebar"},"apps/external-dns":{"id":"apps/external-dns","title":"External-DNS","description":"External-dns is required to make public service domains accessible by registering them with Otomi\'s front loadbalancer CNAME or IP address. When it is not enabled (default) Otomi will instead rely on nip.io to create host names for all services.","sidebar":"mainSidebar"},"apps/falco":{"id":"apps/falco","title":"Falco","description":"Falco can be used for thread detection. When turned on"},"apps/gatekeeper":{"id":"apps/gatekeeper","title":"Gatekeeper","description":"Otomi offers Kubernetes security best practices through security constraints defined as OPA policies and enforced by Gatekeeper.","sidebar":"mainSidebar"},"apps/gitea":{"id":"apps/gitea","title":"Gitea","description":"Gitea is a community managed lightweight code hosting solution written in Go. Because Otomi uses Drone to deploy changes to the values repo, it needs a git hosting solution. When no source control is configured, Otomi will deploy Gitea for Drone to target as a git repo. Gitea may be used for other purposes, and is especially useful in combination with Drone as a CI/CD solution. Just like Otomi uses it.","sidebar":"mainSidebar"},"apps/grafana":{"id":"apps/grafana","title":"Grafana","description":"Otomi uses Grafana to visualize Prometheus metrics and Loki logs. Team members are automatically given Editor role, while admins are also given Admin role. It is possible to make configuration changes directly in Grafana, but only to non-conflicting settings. Data sources are preconfigured and must not be edited as changes will be lost when Grafana is redeployed.","sidebar":"mainSidebar"},"apps/harbor":{"id":"apps/harbor","title":"Harbor","description":"Harbor is an open-source registry that secures artifacts with policies and role-based access control, ensures images are scanned and free from vulnerabilities, and signs images as trusted. As a CNCF graduated project, Harbor delivers compliance, performance, and interoperability to help you consistently and securely manage artifacts across cloud-native compute platforms like Kubernetes. (source//goharbor.io/)","sidebar":"mainSidebar"},"apps/ingress-nginx":{"id":"apps/ingress-nginx","title":"NGINX Ingress","description":"Ingress NGINX is the default ingress controller in Otomi and part of the core setup (this means it is not possible use another controller within Otomi).","sidebar":"mainSidebar"},"apps/istio":{"id":"apps/istio","title":"Istio","description":"Since Otomi has security best practices built in, it is designed for intrusion.","sidebar":"mainSidebar"},"apps/jaeger":{"id":"apps/jaeger","title":"Jaeger","description":"Jaeger can be activated by Otomi to gain tracing insights on its network traffic. It runs in anonymous mode and each authenticated user is given the same authorization, allowing them to see everything. In the future this may be limited according to scope such as role and teams.","sidebar":"mainSidebar"},"apps/keycloak":{"id":"apps/keycloak","title":"Keycloak","description":"The SSO login page for Otomi is served by Keycloak. It is used as an identity broker or provider for all Otomi integrated applications. Keycloak is configured with mappers that normalize incoming identities from an IDP to have predictable claims format to be used by Otomi applications.","sidebar":"mainSidebar"},"apps/kiali":{"id":"apps/kiali","title":"Kiali","description":"Kiali can be activated in Otomi to gain observability insights on its network traffic. It runs in anonymous mode and each authenticated user is given the same authorization, allowing them to see everything. In the future this may be limited according to scope such as role and teams."},"apps/knative":{"id":"apps/knative","title":"Knative","description":"Knative can be activated in Otomi to deliver Container-as-a-Service (CaaS) functionality with scale-to-zero possibility. It can be compared to Functions-as-a-service (FaaS) but is container oriented, and takes only one manifest to configure an autoscaling service based on a container image of choice. Otomi uses Istio Virtual Services under the hood to route traffic coming in for a public domain to its backing Knative Service, allowing to set a custom domain.","sidebar":"mainSidebar"},"apps/kubeapps":{"id":"apps/kubeapps","title":"Kubeapps","description":"Kubeapps is a web-based UI for deploying and managing applications in Kubernetes clusters. Kubeapps allows you to:","sidebar":"mainSidebar"},"apps/kubeclarity":{"id":"apps/kubeclarity","title":"Kubeclarity","description":"Kubeclarity can be activated in Otomi to run on-demand scans of running containers in selected namespaces. Otomi also offers Trivy Operator for runtime scanning. Trivy Operator is configured to scan team namespaces only. Kubeclarity is by default configured using Trivy as a scanner and analyser.","sidebar":"mainSidebar"},"apps/loki":{"id":"apps/loki","title":"Loki","description":"Loki aggregates all the container logs from the platform and stores them in a storage endpoint of choice (defaults to PVC). When Otomi is installed in multi-tenancy mode (see here it will split logs from team namespaces and make them available only to team members. Otomi provides shortcuts to selections of logs based on interest. Otomi splits logs per team, installs a dedicated Grafana instance per team and configures authentication for Grafana to allow access for team members only.","sidebar":"mainSidebar"},"apps/minio":{"id":"apps/minio","title":"Minio","description":"Minio can be enabled to provice an in-cluster S3 compatible Object Store service. Minio is by default provisioned to be used by:","sidebar":"mainSidebar"},"apps/prometheus":{"id":"apps/prometheus","title":"Prometheus","description":"Prometheus aggregates all the metrics from the platform and stores them in a storage endpoint of choice (defaults to PVC).","sidebar":"mainSidebar"},"apps/tekton":{"id":"apps/tekton","title":"Tekton","description":"Tekton is used in Otomi for the Builds self-service. When a Build is created, Otomi generates the Tekton Pipeline and Pipelinerun resources. There are 2 types op pipelines:","sidebar":"mainSidebar"},"apps/thanos":{"id":"apps/thanos","title":"Thanos","description":"Thanos can be enabled for multi-cluster long term metrics retention.","sidebar":"mainSidebar"},"apps/trivy":{"id":"apps/trivy","title":"Trivy Operator","description":"Trivy can be enabled to scan all running containers in all team namespaces. When enabled, the team\'s Grafana instance will be configured to provide a dashboard for teams to see all vulnerabilities within their applications.","sidebar":"mainSidebar"},"apps/vault":{"id":"apps/vault","title":"Hashicorp Vault","description":"HashiCorp Vault is a shared application for securely storing and managing secrets. Read more about Vault here.","sidebar":"mainSidebar"},"apps/velero":{"id":"apps/velero","title":"Velero","description":"Velero can be activated for creating backups of PVC\'s and Kubernetes resources.","sidebar":"mainSidebar"},"for-ciso/overview":{"id":"for-ciso/overview","title":"Overview","description":"ISO 27001 controls checklist"},"for-devs/console/apps":{"id":"for-devs/console/apps","title":"Team Apps","description":"The team apps are shared apps on the platform available for teams to use. Click on the app to open the app, or click on the configuration icon to go to the app details:","sidebar":"mainSidebar"},"for-devs/console/builds":{"id":"for-devs/console/builds","title":"Team Builds","description":"A Build in Otomi is a self-service feature for building OCI compliant images based on application source code.","sidebar":"mainSidebar"},"for-devs/console/deploy-changes":{"id":"for-devs/console/deploy-changes","title":"Deploy changes","description":"When a form (build, workload, service, backup, secret) is submitted, Otomi will prepare a commit in the Otomi Values Git repository. When the commit is prepared, the Deploy Changes button in the top of the left menu will become active. To commit your changes, click on the Deploy Changes button.","sidebar":"mainSidebar"},"for-devs/console/projects":{"id":"for-devs/console/projects","title":"Team Projects","description":"A Project in Otomi is a collection of a Build, a Workload and a Service in ONE form.","sidebar":"mainSidebar"},"for-devs/console/secrets":{"id":"for-devs/console/secrets","title":"Team Secrets","description":"Any secret that is created here should have it\'s counterpart in Vault by the same name. Otomi will create kubernetes secrets from those Vault secrets. These can then be used in Otomi Services and Otomi Workloads, as injected env vars, or as file mounts.","sidebar":"mainSidebar"},"for-devs/console/services":{"id":"for-devs/console/services","title":"Team Services","description":"A service in Otomi is a self-service feature for:","sidebar":"mainSidebar"},"for-devs/console/settings":{"id":"for-devs/console/settings","title":"Team Settings","description":"Based on self-service options allowed by the platfrom administrator, team members can change the settings of their team.","sidebar":"mainSidebar"},"for-devs/console/shell":{"id":"for-devs/console/shell","title":"Shell (TTY Console)","description":"The Shell feature allows to start a web based shell in Console with Kube API access. When starting a shell, a dedicated shell instance will be started for the user. The shell includes the following tools:","sidebar":"mainSidebar"},"for-devs/console/shortcuts":{"id":"for-devs/console/shortcuts","title":"Team Shortcuts","description":"The Shortcuts section shows all shortcuts created and available for the team.","sidebar":"mainSidebar"},"for-devs/console/workloads":{"id":"for-devs/console/workloads","title":"Team Workloads","description":"A Workload in Otomi is a self-service feature for:","sidebar":"mainSidebar"},"for-devs/get-started/lab-1":{"id":"for-devs/get-started/lab-1","title":"Prerequisites for getting started","description":"Welcome to Otomi! If you are a developer and are going to use Otomi, this getting started guide is for you. In this first part we are going to make sure everything is ready to get started.","sidebar":"mainSidebar"},"for-devs/get-started/lab-10":{"id":"for-devs/get-started/lab-10","title":"BYO manifest to deploy a workload with Argo CD","description":"Prerequisite: For this lab, Argo CD needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-11":{"id":"for-devs/get-started/lab-11","title":"Configure ArgoCD image updater","description":"In the previous part, you have seen how to use ArgoCD to automatically deploy applications by adding the Kubernetes manifests in to the gitops repo in Gitea. You can also use ArgoCD to deploy Helm charts and automatically update the version of the deployed image.","sidebar":"mainSidebar"},"for-devs/get-started/lab-12":{"id":"for-devs/get-started/lab-12","title":"Deploy a BYO Helm chart","description":"Otomi offers a self-service feature to create 3 types of workloads:","sidebar":"mainSidebar"},"for-devs/get-started/lab-13":{"id":"for-devs/get-started/lab-13","title":"Deploy workloads using Otomi","description":"In the previous 2 parts we have explained how to deploy a workload with a BYO manifest using Kubectl and how to deploy a workload with a BYO manifest using ArgoCD in Otomi. In this part we\'ll deploy a regular workload (a Kubernetes Deployment) using the Otomi Workloads feature.","sidebar":"mainSidebar"},"for-devs/get-started/lab-14":{"id":"for-devs/get-started/lab-14","title":"Deploy serverless workloads","description":"Prerequisite: For this lab, ArgoCD needs to be activated."},"for-devs/get-started/lab-15":{"id":"for-devs/get-started/lab-15","title":"Check policy compliance","description":"Prerequisite: For this lab, Gatekeeper needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-16":{"id":"for-devs/get-started/lab-16","title":"Check for threads","description":"Prerequisite: For this lab, Falco needs to be activated."},"for-devs/get-started/lab-17":{"id":"for-devs/get-started/lab-17","title":"Scan your running containers for vulnerabilities","description":"Prerequisite: For this lab, Trivy needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-18":{"id":"for-devs/get-started/lab-18","title":"Publicly expose your application","description":"When you have deployed your app, you will propably like to expose it publicly. You propably noticed that in the previous part, we created a Kubernetes service of type ClusterIP and not LoadBalancer and also that the Pod(s) created by the deployment have an Istio sidecar. All Pods created in your team will automatically be added to the service mesh. In this part we\'ll create a Service in Otomi to expose your app publicly. When you create a Service, Otomi will then create the Istio virtual service and configure ingress for your application.","sidebar":"mainSidebar"},"for-devs/get-started/lab-19":{"id":"for-devs/get-started/lab-19","title":"Configuring network policies","description":"In some cases you want to explicitly allow access to your application. This can be done by creating network policies. Otomi supports 2 types of network policies:","sidebar":"mainSidebar"},"for-devs/get-started/lab-2":{"id":"for-devs/get-started/lab-2","title":"Access Otomi Console and download the KUBECFG","description":"When you have received the URL of the web UI of Otomi Platform and have a username/password with access permissions, then it\'s time to sign-in","sidebar":"mainSidebar"},"for-devs/get-started/lab-20":{"id":"for-devs/get-started/lab-20","title":"View container logs","description":"Prerequisite: For this lab, Loki and Grafana need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-21":{"id":"for-devs/get-started/lab-21","title":"View container metrics","description":"Prerequisite: For this lab, Prometheus and Grafana need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-22":{"id":"for-devs/get-started/lab-22","title":"Using custom metrics","description":"Prerequisite: For this lab, Prometheus and Grafana need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-23":{"id":"for-devs/get-started/lab-23","title":"Monitoring service availability","description":"When your application is deployed, you would of course like to get an alert when you application (service) is not available anymore. To automatically monitor you applications for availability, Otomi automatically configures a prope to monitor your service.","sidebar":"mainSidebar"},"for-devs/get-started/lab-24":{"id":"for-devs/get-started/lab-24","title":"Create a PostgreSQL database","description":"Otomi by defalt installs the Cloudnative-gp database operator. Teams can use the operator to create their own PostgreSQL databases.","sidebar":"mainSidebar"},"for-devs/get-started/lab-25":{"id":"for-devs/get-started/lab-25","title":"Monitor PostgreSQL databases","description":"If you previously created a database, you\'ll noticed that we did not let the operator create a PodMonitor. The reason of this, is that the PodMonitor requires specific lables to be picked-up by the team\'s own Prometheus. In this lab we\'ll create a custom PodMonitor and create a dashboard in the team\'s own Grafana.","sidebar":"mainSidebar"},"for-devs/get-started/lab-26":{"id":"for-devs/get-started/lab-26","title":"Trigger builds","description":"In the previous lab we created a build in Otomi using a public code repository. In this lab we\'ll create a build based on a private code repo in the local Gitea and trigger the build based on a webhook.","sidebar":"mainSidebar"},"for-devs/get-started/lab-3":{"id":"for-devs/get-started/lab-3","title":"Create a private Git repo","description":"As a developer you\'ll need a Git repository for your code. Most organizations will probably have a central code repository like Gitlab, or use Github. But if you don\'t, Otomi has you covered. Otomi includes a complete self-hosted Git solution called Gitea.","sidebar":"mainSidebar"},"for-devs/get-started/lab-4":{"id":"for-devs/get-started/lab-4","title":"Create a CI pipeline","description":"Kubernetes is a container orchestrator, so we need to create container images that we can deploy. Next to providing a Git service. Otomi also has a complete CI solution called Drone integrated. You can use Drone to create and run CI pipelines to build images and push them to your private image registry (Harbor).","sidebar":"mainSidebar"},"for-devs/get-started/lab-5":{"id":"for-devs/get-started/lab-5","title":"Push your container images","description":"Prerequisite: For this lab, Harbor needs to be activated and the cluster needs to be configured with trusted certificates (like Let\'s Encrypt using production certificate).","sidebar":"mainSidebar"},"for-devs/get-started/lab-6":{"id":"for-devs/get-started/lab-6","title":"Build images from application source","description":"Prerequisite: For this lab, Harbor and Tekton need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-7":{"id":"for-devs/get-started/lab-7","title":"Scan your images for vulnerabilities","description":"When your team is using Harbor for private image registries, you can use Trivy to automatically scan your images on push. This is not enabled by default. Ask your platform administrator to turn this on for your project in Harbor. When enabled, you can see the results of the scans by following these steps:","sidebar":"mainSidebar"},"for-devs/get-started/lab-8":{"id":"for-devs/get-started/lab-8","title":"Create secrets","description":"Prerequisite: For this lab, Hashicorp Vault needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-9":{"id":"for-devs/get-started/lab-9","title":"Deploy your application","description":"Now that you have access to the team namespace and have pushed your image to Harbor, you can now deploy your application."},"for-devs/get-started/overview":{"id":"for-devs/get-started/overview","title":"Get started with Otomi for Developers","description":"Welcome to Otomi! If you are a developer and are going to use Otomi Platform, these getting started labs are for you. Step by step we\'ll guide you in using Otomi to deploy and manage your containerized applications. The getting started with Otomi for developers contains a set of labs to cover the most common developer activities.","sidebar":"mainSidebar"},"for-ops/cli/apply":{"id":"for-ops/cli/apply","title":"otomi apply","description":"otomi apply [options]","sidebar":"mainSidebar"},"for-ops/cli/bash":{"id":"for-ops/cli/bash","title":"otomi bash","description":"otomi bash","sidebar":"mainSidebar"},"for-ops/cli/bootstrap":{"id":"for-ops/cli/bootstrap","title":"otomi bootstrap","description":"otomi bootstrap [options]","sidebar":"mainSidebar"},"for-ops/cli/check-policies":{"id":"for-ops/cli/check-policies","title":"check-policies","description":"otomi check-policies [options]","sidebar":"mainSidebar"},"for-ops/cli/commit":{"id":"for-ops/cli/commit","title":"otomi commit","description":"otomi commit [options]","sidebar":"mainSidebar"},"for-ops/cli/decrypt":{"id":"for-ops/cli/decrypt","title":"otomi decrypt","description":"otomi decrypt [options]","sidebar":"mainSidebar"},"for-ops/cli/deploying":{"id":"for-ops/cli/deploying","title":"Using Otomi CLI","description":"1. Initialize a values repo","sidebar":"mainSidebar"},"for-ops/cli/destroy":{"id":"for-ops/cli/destroy","title":"otomi destroy","description":"otomi destroy [options]","sidebar":"mainSidebar"},"for-ops/cli/diff":{"id":"for-ops/cli/diff","title":"otomi diff","description":"otomi diff [options]","sidebar":"mainSidebar"},"for-ops/cli/encrypt":{"id":"for-ops/cli/encrypt","title":"otomi encrypt","description":"otomi encrypt [files...] [options]","sidebar":"mainSidebar"},"for-ops/cli/installation":{"id":"for-ops/cli/installation","title":"Installing and using Otomi CLI","description":"Prerequisites","sidebar":"mainSidebar"},"for-ops/cli/known-issues":{"id":"for-ops/cli/known-issues","title":"Known Issues","description":"The otomi (diff|apply|sync|template) commands are delegated to helmfile, which in turn delegates the deployment work to helm. Sometimes it is not clear wether the issue is from Helm or Helmfile, so we will address them together in this section.","sidebar":"mainSidebar"},"for-ops/cli/lint":{"id":"for-ops/cli/lint","title":"otomi lint","description":"otomi lint [options]","sidebar":"mainSidebar"},"for-ops/cli/pull":{"id":"for-ops/cli/pull","title":"otomi pull","description":"otomi pull [options]","sidebar":"mainSidebar"},"for-ops/cli/rotate-keys":{"id":"for-ops/cli/rotate-keys","title":"otomi rotate-keys","description":"otomi rotate-keys [options]","sidebar":"mainSidebar"},"for-ops/cli/status":{"id":"for-ops/cli/status","title":"otomi status","description":"otomi status [options]","sidebar":"mainSidebar"},"for-ops/cli/sync":{"id":"for-ops/cli/sync","title":"otomi sync","description":"otomi sync [options]","sidebar":"mainSidebar"},"for-ops/cli/template":{"id":"for-ops/cli/template","title":"otomi template","description":"otomi template [options]","sidebar":"mainSidebar"},"for-ops/cli/test":{"id":"for-ops/cli/test","title":"otomi test","description":"otomi test [options]","sidebar":"mainSidebar"},"for-ops/cli/validate-templates":{"id":"for-ops/cli/validate-templates","title":"otomi validate-templates","description":"otomi validate-templates [options]","sidebar":"mainSidebar"},"for-ops/cli/validate-values":{"id":"for-ops/cli/validate-values","title":"otomi validate-values","description":"otomi validate-values [options]","sidebar":"mainSidebar"},"for-ops/cli/values":{"id":"for-ops/cli/values","title":"otomi values","description":"otomi values [options]","sidebar":"mainSidebar"},"for-ops/cli/x":{"id":"for-ops/cli/x","title":"otomi x","description":"otomi x","sidebar":"mainSidebar"},"for-ops/console/apps":{"id":"for-ops/console/apps","title":"Platform - Apps","description":"The apps section lists all apps available.","sidebar":"mainSidebar"},"for-ops/console/backups":{"id":"for-ops/console/backups","title":"Platform - Backups","description":"To enable this feature, first make sure Velero is activated.","sidebar":"mainSidebar"},"for-ops/console/builds":{"id":"for-ops/console/builds","title":"Platform - Builds","description":"To enable this feature, first make sure Harbor and Tekton are activated. To be able to push images to Harbor, Otomi needs to be configured with a DNS and trusted certificates (Lets encrypt with production certificates).","sidebar":"mainSidebar"},"for-ops/console/clusters":{"id":"for-ops/console/clusters","title":"Platform - Clusters","description":"All known Otomi clusters are listed here. Clusters can be sorted based on:","sidebar":"mainSidebar"},"for-ops/console/deploy-changes":{"id":"for-ops/console/deploy-changes","title":"Deploy changes","description":"When a change has been made, by pressing Submit, the Deploy Changes button will light up to deploy the changes you have made in the console. This will create a commit of the changes to the values repository in Gitea and trigger the Drone pipeline run."},"for-ops/console/overview":{"id":"for-ops/console/overview","title":"Overview","description":"Otomi Console","sidebar":"mainSidebar"},"for-ops/console/policies":{"id":"for-ops/console/policies","title":"Platform - Policies","description":"To enable this feature, first make sure OPA/Gatekeeper is activated.","sidebar":"mainSidebar"},"for-ops/console/projects":{"id":"for-ops/console/projects","title":"Projects","description":"A Project in Otomi is a collection of a Build, a Workload and a Service in ONE form. When a user creates a project, the name of the project will be used for all created tasks (build, workload, service).","sidebar":"mainSidebar"},"for-ops/console/secrets":{"id":"for-ops/console/secrets","title":"Platform - Secrets","description":"To enable this feature, first make sure Hashicorp Vault is activated.","sidebar":"mainSidebar"},"for-ops/console/services":{"id":"for-ops/console/services","title":"Platform - Services","description":"All known Services on the platform are listed here. Services can be sorted based on:","sidebar":"mainSidebar"},"for-ops/console/settings/alerts":{"id":"for-ops/console/settings/alerts","title":"Platform settings","description":"Alerts","sidebar":"mainSidebar"},"for-ops/console/settings/azure":{"id":"for-ops/console/settings/azure","title":"Platform settings","description":"Azure","sidebar":"mainSidebar"},"for-ops/console/settings/backup":{"id":"for-ops/console/settings/backup","title":"Platform settings","description":"Backup","sidebar":"mainSidebar"},"for-ops/console/settings/cluster":{"id":"for-ops/console/settings/cluster","title":"Platform settings","description":"Cluster","sidebar":"mainSidebar"},"for-ops/console/settings/co-monitoring":{"id":"for-ops/console/settings/co-monitoring","title":"Platform settings","description":"Co-Monitoring","sidebar":"mainSidebar"},"for-ops/console/settings/dns":{"id":"for-ops/console/settings/dns","title":"Platform settings","description":"DNS","sidebar":"mainSidebar"},"for-ops/console/settings/ingress":{"id":"for-ops/console/settings/ingress","title":"Platform settings","description":"Ingress","sidebar":"mainSidebar"},"for-ops/console/settings/key-management":{"id":"for-ops/console/settings/key-management","title":"Platform settings","description":"Key management","sidebar":"mainSidebar"},"for-ops/console/settings/oidc":{"id":"for-ops/console/settings/oidc","title":"Platform settings","description":"OIDC","sidebar":"mainSidebar"},"for-ops/console/settings/otomi":{"id":"for-ops/console/settings/otomi","title":"Platform settings","description":"Otomi","sidebar":"mainSidebar"},"for-ops/console/settings/smtp":{"id":"for-ops/console/settings/smtp","title":"Platform settings","description":"SMTP","sidebar":"mainSidebar"},"for-ops/console/shell":{"id":"for-ops/console/shell","title":"Shell","description":"The Shell feature allows to start a web based shell in Console with Kube API access. When starting a shell, a dedicated shell instance will be started for the user. The shell includes the following tools:","sidebar":"mainSidebar"},"for-ops/console/shortcuts":{"id":"for-ops/console/shortcuts","title":"Platform - Shortcuts","description":"The Shortcuts section shows all shortcuts created and available on the platform for users with the otomi-admin role.","sidebar":"mainSidebar"},"for-ops/console/teams":{"id":"for-ops/console/teams","title":"Platform - Teams","description":"- Teams are tenants on the platform to support Development/DevOps teams, projects or even DTAP","sidebar":"mainSidebar"},"for-ops/console/workloads":{"id":"for-ops/console/workloads","title":"Platform - Workloads","description":"To enable this feature, first make sure ArgoCD is activated.","sidebar":"mainSidebar"},"for-ops/how-to/core-only":{"id":"for-ops/how-to/core-only","title":"Use Otomi Core only","description":"Otomi by default installs Gitea, Drone, Otomi API and Otomi Console. Otomi Console is the self-service UI and uses Otomi API to generate validated configuration code. This configuration code is then committed to Gitea (in the values repository), which will trigger teh pre-configured Drone pipeline to apply the changes.","sidebar":"mainSidebar"},"for-ops/how-to/create-and-restore-backups":{"id":"for-ops/how-to/create-and-restore-backups","title":"Create/Restore backups","description":"When Velero is activated on the platform level, platform admins can create backups of Persistent Volumes (PVs) in Team namespaces using Otomi Console. When creating backups using Otomi Console, a Velero schedule resource is created that will create the backup at a specified time, defined by a Cron expression.","sidebar":"mainSidebar"},"for-ops/how-to/ingress-classes":{"id":"for-ops/how-to/ingress-classes","title":"Use private ingress class","description":"When Otomi is installed, exposure (ingress) for all services (included exposure for platform services) is handeled by the default platform ingress class using a public (cloud) load balancer. Otomi offers the option to use multiple ingress classes. Each class get a dedicated ingress controller. In case of security requirements, where platform services are not allowed to be exposed publicly, the default platform class can be configured to use a private load balancer instead of a public one. Additional (public) ingress classes can be created to expose team (application) services.","sidebar":"mainSidebar"},"for-ops/how-to/install-with-dns":{"id":"for-ops/how-to/install-with-dns","title":"Install Otomi with DNS","description":"Route53","sidebar":"mainSidebar"},"for-ops/how-to/switch-to-dns":{"id":"for-ops/how-to/switch-to-dns","title":"Switch to use DNS","description":"When Otomi is installed with minimal values, a custom CA is generated and Otomi uses nip.io for host names. It is possible to switch from nip.io to using a DNS zone after installing Otomi initially without DNS. To switch from nip.io to a DNS zone, follow the instructions as described below."},"for-ops/how-to/use-team-admin":{"id":"for-ops/how-to/use-team-admin","title":"Use team-admin","description":"When Otomi is installed, by default a team called team-admin is created. The Admin Team is no regular team. This team for instance has no apps. Instead the admin needs to use the platform apps to see logs and metrics of workloads deployed in the team-admin namespace.","sidebar":"mainSidebar"},"for-ops/sre/daily":{"id":"for-ops/sre/daily","title":"SRE Daily Routine","description":"As an SRE you would like to keep your daily tasks to a minimum and be automatically informed on issues. Otomi offers the following tooling to automate this:","sidebar":"mainSidebar"},"for-ops/sre/overview":{"id":"for-ops/sre/overview","title":"SRE Overview","description":"Otomi is a set of functions built on top of a suite of pre-configured and integrated open source applications. Instead of selecting, configuring, and integrating all the parts that are needed to securely manage containerized applications in multi- and hybrid environments, Otomi offers all required parts in a single package. Otomi can be seen as any other Kubernetes application or add-on, with the difference that Otomi is pre-configured and offers a higher abstraction of configuration for all the integrated solutions. All integrated applications can however be used freely, meaning that a user can benefit from the pre-configuration to start using the offered applications.","sidebar":"mainSidebar"},"for-ops/sre/troubleshooting":{"id":"for-ops/sre/troubleshooting","title":"SRE Troubleshooting Checklist","description":"Pods not starting","sidebar":"mainSidebar"},"for-ops/sre/upgrades":{"id":"for-ops/sre/upgrades","title":"Upgrades","description":"Introduction","sidebar":"mainSidebar"},"get-started/activation":{"id":"get-started/activation","title":"Activation steps","description":"Follow the steps below to activate Otomi after initial installation.","sidebar":"mainSidebar"},"get-started/chart":{"id":"get-started/chart","title":"Install from chart","description":"Use Helm to install Otomi."},"get-started/installation":{"id":"get-started/installation","title":"Installation","description":"Install Otomi with Helm","sidebar":"mainSidebar"},"get-started/optional":{"id":"get-started/optional","title":"Optional configuration","description":"You can optionally configure Otomi to use an external IDP (Azure AD), use an external Key Management Service (KMS) provider for SOPS and use a DNS zone in combination with LetsEncrpt certificates. Below you can find detailed instructions on how to set up Azure AD as an external IDP and configure KMS. We will soon add more instructions for other IDPs, such as Amazon Incognito, Google Identity, and Okta."},"get-started/prerequisites":{"id":"get-started/prerequisites","title":"Prerequisites","description":"Client binaries","sidebar":"mainSidebar"},"tutorials/overview":{"id":"tutorials/overview","title":"Tutorial Overview","description":"This section contains tutorials for more advanced installation scenario\'s."},"tutorials/tutorial-1":{"id":"tutorials/tutorial-1","title":"Installing Otomi","description":"To go through the tutorials, you first need to install Otomi on a running Kubernetes cluster."},"tutorials/tutorial-10":{"id":"tutorials/tutorial-10","title":"Creating a micro service architecture","description":"In this tutorial we are going to deploy multiple services from different teams and expose them using a shared domain, but each on their own path. We will use on-the-fly Knative services for speed and simplicity."},"tutorials/tutorial-2":{"id":"tutorials/tutorial-2","title":"Creating teams","description":"In this tutorial, we are going to create a Team in Otomi. Teams in Otomi serve the following purpose:"},"tutorials/tutorial-3":{"id":"tutorials/tutorial-3","title":"Activating tools","description":"Core Apps"},"tutorials/tutorial-4":{"id":"tutorials/tutorial-4","title":"Build, tag and push an image to Harbor","description":"When Otomi is installed without using Let\'s Encrypt production certificates, make sure you download the CA.crt, add it to your Keychain and restarted Docker."},"tutorials/tutorial-5":{"id":"tutorials/tutorial-5","title":"Create a Workload","description":"In his tutorial, we are going to create a Workload in Otomi."},"tutorials/tutorial-6":{"id":"tutorials/tutorial-6","title":"Create a Service","description":"In his tutorial, we are going to create a Service in Otomi to publicly expose the ClusterIP service of the Workload we deployed in the previous tutorial."},"tutorials/tutorial-7":{"id":"tutorials/tutorial-7","title":"Using Knative","description":"In this lab, we are going to:"},"tutorials/tutorial-8":{"id":"tutorials/tutorial-8","title":"Using secrets","description":"In his tutorial, you are going to:"},"tutorials/tutorial-9":{"id":"tutorials/tutorial-9","title":"Configuring network policies","description":"In this tutorial we are going to deploy a multi tier web application, called guestbook, register the 3 K8s services in Otomi and configure public access to the frontend service. Next, we will turn on the Network policies option for the team."},"tutorials/tutorial-create-byo-ksvc":{"id":"tutorials/tutorial-create-byo-ksvc","title":"Create a Knative service","description":"In this tutorial, you are going to deploy the image you build, tagged and pushed to harbor in the previous tutorial by creating a Knative service."},"tutorials/tutorial-create-byo-svc":{"id":"tutorials/tutorial-create-byo-svc","title":"Create a Kubernetes service","description":"In this tutorial, we are going to deploy the image we pushed to harbor in the previous tutorial, by creating a Kubernetes Deployment and Service."},"tutorials/tutorial-create-otomi-ksvc":{"id":"tutorials/tutorial-create-otomi-ksvc","title":"Create and expose a Knative service with Otomi","description":"In his tutorial, we are going to create a Knative service with Otomi Console and publicly expose it."},"tutorials/tutorial-use-secrets":{"id":"tutorials/tutorial-use-secrets","title":"Use secrets in Kubernetes","description":"In his tutorial, you are going to use the secret created in Hashicorp Vault and added to Kubernetes using the Otomi Secrets feature in a Kubernetes deployment."}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.e6d8328b.js b/assets/js/935f2afb.e6d8328b.js deleted file mode 100644 index 1bd7538ca..000000000 --- a/assets/js/935f2afb.e6d8328b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"mainSidebar":[{"type":"category","label":"Getting Started","items":[{"type":"link","label":"Prerequisites","href":"/docs/get-started/prerequisites","docId":"get-started/prerequisites"},{"type":"link","label":"Installation","href":"/docs/get-started/installation","docId":"get-started/installation"},{"type":"link","label":"Activation","href":"/docs/get-started/activation","docId":"get-started/activation"},{"type":"link","label":"Get Started Labs","href":"/docs/for-devs/get-started/overview","docId":"for-devs/get-started/overview"}],"collapsed":true,"collapsible":true},{"type":"category","label":"For Ops","items":[{"type":"category","label":"Otomi Console","items":[{"type":"link","label":"Overview","href":"/docs/for-ops/console/overview","docId":"for-ops/console/overview"},{"type":"link","label":"Apps","href":"/docs/for-ops/console/apps","docId":"for-ops/console/apps"},{"type":"link","label":"Shortcuts","href":"/docs/for-ops/console/shortcuts","docId":"for-ops/console/shortcuts"},{"type":"link","label":"Clusters","href":"/docs/for-ops/console/clusters","docId":"for-ops/console/clusters"},{"type":"link","label":"Policies","href":"/docs/for-ops/console/policies","docId":"for-ops/console/policies"},{"type":"link","label":"Teams","href":"/docs/for-ops/console/teams","docId":"for-ops/console/teams"},{"type":"link","label":"Projects","href":"/docs/for-ops/console/projects","docId":"for-ops/console/projects"},{"type":"link","label":"Builds","href":"/docs/for-ops/console/builds","docId":"for-ops/console/builds"},{"type":"link","label":"Secrets","href":"/docs/for-ops/console/secrets","docId":"for-ops/console/secrets"},{"type":"link","label":"Workloads","href":"/docs/for-ops/console/workloads","docId":"for-ops/console/workloads"},{"type":"link","label":"Services","href":"/docs/for-ops/console/services","docId":"for-ops/console/services"},{"type":"link","label":"Backups","href":"/docs/for-ops/console/backups","docId":"for-ops/console/backups"},{"type":"link","label":"Shell","href":"/docs/for-ops/console/shell","docId":"for-ops/console/shell"},{"type":"category","label":"Settings","items":[{"type":"link","label":"Cluster","href":"/docs/for-ops/console/settings/cluster","docId":"for-ops/console/settings/cluster"},{"type":"link","label":"Otomi","href":"/docs/for-ops/console/settings/otomi","docId":"for-ops/console/settings/otomi"},{"type":"link","label":"Key Management","href":"/docs/for-ops/console/settings/key-management","docId":"for-ops/console/settings/key-management"},{"type":"link","label":"Alerts","href":"/docs/for-ops/console/settings/alerts","docId":"for-ops/console/settings/alerts"},{"type":"link","label":"Co-monitoring","href":"/docs/for-ops/console/settings/co-monitoring","docId":"for-ops/console/settings/co-monitoring"},{"type":"link","label":"Azure","href":"/docs/for-ops/console/settings/azure","docId":"for-ops/console/settings/azure"},{"type":"link","label":"DNS","href":"/docs/for-ops/console/settings/dns","docId":"for-ops/console/settings/dns"},{"type":"link","label":"Ingress","href":"/docs/for-ops/console/settings/ingress","docId":"for-ops/console/settings/ingress"},{"type":"link","label":"OIDC","href":"/docs/for-ops/console/settings/oidc","docId":"for-ops/console/settings/oidc"},{"type":"link","label":"SMTP","href":"/docs/for-ops/console/settings/smtp","docId":"for-ops/console/settings/smtp"},{"type":"link","label":"Backup","href":"/docs/for-ops/console/settings/backup","docId":"for-ops/console/settings/backup"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"How To","items":[{"type":"link","label":"Use private ingress class","href":"/docs/for-ops/how-to/ingress-classes","docId":"for-ops/how-to/ingress-classes"},{"type":"link","label":"Use Team Admin","href":"/docs/for-ops/how-to/use-team-admin","docId":"for-ops/how-to/use-team-admin"},{"type":"link","label":"Use Core only","href":"/docs/for-ops/how-to/core-only","docId":"for-ops/how-to/core-only"},{"type":"link","label":"Install with DNS","href":"/docs/for-ops/how-to/install-with-dns","docId":"for-ops/how-to/install-with-dns"},{"type":"link","label":"Backups","href":"/docs/for-ops/how-to/backups","docId":"for-ops/how-to/create-and-restore-backups"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Otomi CLI","items":[{"type":"link","label":"Installation","href":"/docs/for-ops/cli/installation","docId":"for-ops/cli/installation"},{"type":"link","label":"Using Otomi CLI","href":"/docs/for-ops/cli/deploying","docId":"for-ops/cli/deploying"},{"type":"link","label":"Known issues","href":"/docs/for-ops/cli/known-issues","docId":"for-ops/cli/known-issues"},{"type":"category","label":"CLI Commands","items":[{"type":"link","label":"otomi apply","href":"/docs/for-ops/cli/apply","docId":"for-ops/cli/apply"},{"type":"link","label":"otomi bash","href":"/docs/for-ops/cli/bash","docId":"for-ops/cli/bash"},{"type":"link","label":"otomi bootstrap","href":"/docs/for-ops/cli/bootstrap","docId":"for-ops/cli/bootstrap"},{"type":"link","label":"otomi check-policies","href":"/docs/for-ops/cli/check-policies","docId":"for-ops/cli/check-policies"},{"type":"link","label":"otomi commit","href":"/docs/for-ops/cli/commit","docId":"for-ops/cli/commit"},{"type":"link","label":"otomi decrypt","href":"/docs/for-ops/cli/decrypt","docId":"for-ops/cli/decrypt"},{"type":"link","label":"otomi destroy","href":"/docs/for-ops/cli/destroy","docId":"for-ops/cli/destroy"},{"type":"link","label":"otomi diff","href":"/docs/for-ops/cli/diff","docId":"for-ops/cli/diff"},{"type":"link","label":"otomi encrypt","href":"/docs/for-ops/cli/encrypt","docId":"for-ops/cli/encrypt"},{"type":"link","label":"otomi lint","href":"/docs/for-ops/cli/lint","docId":"for-ops/cli/lint"},{"type":"link","label":"otomi pull","href":"/docs/for-ops/cli/pull","docId":"for-ops/cli/pull"},{"type":"link","label":"otomi rotate-keys","href":"/docs/for-ops/cli/rotate-keys","docId":"for-ops/cli/rotate-keys"},{"type":"link","label":"otomi status","href":"/docs/for-ops/cli/status","docId":"for-ops/cli/status"},{"type":"link","label":"otomi sync","href":"/docs/for-ops/cli/sync","docId":"for-ops/cli/sync"},{"type":"link","label":"otomi template","href":"/docs/for-ops/cli/template","docId":"for-ops/cli/template"},{"type":"link","label":"otomi test","href":"/docs/for-ops/cli/test","docId":"for-ops/cli/test"},{"type":"link","label":"otomi validate-templates","href":"/docs/for-ops/cli/validate-templates","docId":"for-ops/cli/validate-templates"},{"type":"link","label":"otomi validate-values","href":"/docs/for-ops/cli/validate-values","docId":"for-ops/cli/validate-values"},{"type":"link","label":"otomi values","href":"/docs/for-ops/cli/values","docId":"for-ops/cli/values"},{"type":"link","label":"otomi x","href":"/docs/for-ops/cli/x","docId":"for-ops/cli/x"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"SRE","items":[{"type":"link","label":"Overview","href":"/docs/for-ops/sre/overview","docId":"for-ops/sre/overview"},{"type":"link","label":"Daily Routine","href":"/docs/for-ops/sre/daily","docId":"for-ops/sre/daily"},{"type":"link","label":"Upgrades","href":"/docs/for-ops/sre/upgrades","docId":"for-ops/sre/upgrades"},{"type":"link","label":"Troubleshooting","href":"/docs/for-ops/sre/troubleshooting","docId":"for-ops/sre/troubleshooting"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"For Devs","items":[{"type":"category","label":"Otomi Console","items":[{"type":"link","label":"Apps","href":"/docs/for-devs/console/apps","docId":"for-devs/console/apps"},{"type":"link","label":"Shortcuts","href":"/docs/for-devs/console/shortcuts","docId":"for-devs/console/shortcuts"},{"type":"link","label":"Projects","href":"/docs/for-devs/console/projects","docId":"for-devs/console/projects"},{"type":"link","label":"Builds","href":"/docs/for-devs/console/builds","docId":"for-devs/console/builds"},{"type":"link","label":"Workloads","href":"/docs/for-devs/console/workloads","docId":"for-devs/console/workloads"},{"type":"link","label":"Services","href":"/docs/for-devs/console/services","docId":"for-devs/console/services"},{"type":"link","label":"Secrets","href":"/docs/for-devs/console/secrets","docId":"for-devs/console/secrets"},{"type":"link","label":"Shell","href":"/docs/for-devs/console/shell","docId":"for-devs/console/shell"},{"type":"link","label":"Deploy Changes","href":"/docs/for-devs/console/deploy-changes","docId":"for-devs/console/deploy-changes"},{"type":"link","label":"Settings","href":"/docs/for-devs/console/settings","docId":"for-devs/console/settings"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Get Started With Otomi","items":[{"type":"link","label":"Get Started Labs","href":"/docs/for-devs/get-started/overview","docId":"for-devs/get-started/overview"},{"type":"link","label":"Prerequisites","href":"/docs/for-devs/get-started/lab-1","docId":"for-devs/get-started/lab-1"},{"type":"link","label":"Access Console","href":"/docs/for-devs/get-started/lab-2","docId":"for-devs/get-started/lab-2"},{"type":"link","label":"Create repo","href":"/docs/for-devs/get-started/lab-3","docId":"for-devs/get-started/lab-3"},{"type":"link","label":"Create a custom CI pipeline","href":"/docs/for-devs/get-started/lab-4","docId":"for-devs/get-started/lab-4"},{"type":"link","label":"Push images","href":"/docs/for-devs/get-started/lab-5","docId":"for-devs/get-started/lab-5"},{"type":"link","label":"Build images with Otomi","href":"/docs/for-devs/get-started/lab-6","docId":"for-devs/get-started/lab-6"},{"type":"link","label":"Scan images","href":"/docs/for-devs/get-started/lab-7","docId":"for-devs/get-started/lab-7"},{"type":"link","label":"Create secrets","href":"/docs/for-devs/get-started/lab-8","docId":"for-devs/get-started/lab-8"},{"type":"link","label":"Using Argo CD","href":"/docs/for-devs/get-started/lab-10","docId":"for-devs/get-started/lab-10"},{"type":"link","label":"Use auto image updater","href":"/docs/for-devs/get-started/lab-11","docId":"for-devs/get-started/lab-11"},{"type":"link","label":"Create BYO workload","href":"/docs/for-devs/get-started/lab-12","docId":"for-devs/get-started/lab-12"},{"type":"link","label":"Create Otomi workload","href":"/docs/for-devs/get-started/lab-13","docId":"for-devs/get-started/lab-13"},{"type":"link","label":"Create a database","href":"/docs/for-devs/get-started/lab-24","docId":"for-devs/get-started/lab-24"},{"type":"link","label":"Check policy compliance","href":"/docs/for-devs/get-started/lab-15","docId":"for-devs/get-started/lab-15"},{"type":"link","label":"Scan running containers","href":"/docs/for-devs/get-started/lab-17","docId":"for-devs/get-started/lab-17"},{"type":"link","label":"Expose services","href":"/docs/for-devs/get-started/lab-18","docId":"for-devs/get-started/lab-18"},{"type":"link","label":"Configure network policies","href":"/docs/for-devs/get-started/lab-19","docId":"for-devs/get-started/lab-19"},{"type":"link","label":"View container logs","href":"/docs/for-devs/get-started/lab-20","docId":"for-devs/get-started/lab-20"},{"type":"link","label":"View container metrics","href":"/docs/for-devs/get-started/lab-21","docId":"for-devs/get-started/lab-21"},{"type":"link","label":"Using custom metrics","href":"/docs/for-devs/get-started/lab-22","docId":"for-devs/get-started/lab-22"},{"type":"link","label":"Monitor services","href":"/docs/for-devs/get-started/lab-23","docId":"for-devs/get-started/lab-23"},{"type":"link","label":"Monitor databases","href":"/docs/for-devs/get-started/lab-25","docId":"for-devs/get-started/lab-25"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Otomi Applications","items":[{"type":"link","label":"Alertmanager","href":"/docs/apps/alertmanager","docId":"apps/alertmanager"},{"type":"link","label":"ArgoCD","href":"/docs/apps/argocd","docId":"apps/argocd"},{"type":"link","label":"Cert-Manager","href":"/docs/apps/certmanager","docId":"apps/certmanager"},{"type":"link","label":"Drone","href":"/docs/apps/drone","docId":"apps/drone"},{"type":"link","label":"ExternalDNS","href":"/docs/apps/external-dns","docId":"apps/external-dns"},{"type":"link","label":"Gatekeeper","href":"/docs/apps/gatekeeper","docId":"apps/gatekeeper"},{"type":"link","label":"Gitea","href":"/docs/apps/gitea","docId":"apps/gitea"},{"type":"link","label":"Grafana","href":"/docs/apps/grafana","docId":"apps/grafana"},{"type":"link","label":"Harbor","href":"/docs/apps/harbor","docId":"apps/harbor"},{"type":"link","label":"Ingress-nginx","href":"/docs/apps/ingress-nginx","docId":"apps/ingress-nginx"},{"type":"link","label":"Istio","href":"/docs/apps/istio","docId":"apps/istio"},{"type":"link","label":"Jaeger","href":"/docs/apps/jaeger","docId":"apps/jaeger"},{"type":"link","label":"Keycloak","href":"/docs/apps/keycloak","docId":"apps/keycloak"},{"type":"link","label":"Knative","href":"/docs/apps/knative","docId":"apps/knative"},{"type":"link","label":"Kubeapps","href":"/docs/apps/kubeapps","docId":"apps/kubeapps"},{"type":"link","label":"Kubeclarity","href":"/docs/apps/kubeclarity","docId":"apps/kubeclarity"},{"type":"link","label":"Loki","href":"/docs/apps/loki","docId":"apps/loki"},{"type":"link","label":"Minio","href":"/docs/apps/minio","docId":"apps/minio"},{"type":"link","label":"Prometheus","href":"/docs/apps/prometheus","docId":"apps/prometheus"},{"type":"link","label":"Thanos","href":"/docs/apps/thanos","docId":"apps/thanos"},{"type":"link","label":"Trivy Operator","href":"/docs/apps/trivy","docId":"apps/trivy"},{"type":"link","label":"Tekton","href":"/docs/apps/tekton","docId":"apps/tekton"},{"type":"link","label":"Hashicorp Vault","href":"/docs/apps/vault","docId":"apps/vault"},{"type":"link","label":"Velero","href":"/docs/apps/velero","docId":"apps/velero"}],"collapsed":true,"collapsible":true}]},"docs":{"apps/alertmanager":{"id":"apps/alertmanager","title":"Alertmanager","description":"Alertmanager handles alerts sent by client applications such as the Prometheus server. It takes care of de-duplicating, grouping, and routing them to the correct receiver integration such as email, Slack, MS Teams, or OpsGenie. It also takes care of silencing and inhibition of alerts.","sidebar":"mainSidebar"},"apps/argocd":{"id":"apps/argocd","title":"ArgoCD","description":"ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes. ArgoCD is configured by Otomi to use the SSO provided by keycloak, and maps otomi groups to ArgoCD roles. The otomi-admin role is made super admin within ArgoCD. The team-admin role has access to ArgoCD and is admin of all team projects. Members of team roles are only allowed to administer their own projects. All Teams will automatically get access to a Git repo, and ArgoCD is configured to listen to this repo. All a team has to do is to fill their repo with intended state, commit, and automation takes care of the rest.","sidebar":"mainSidebar"},"apps/certmanager":{"id":"apps/certmanager","title":"CertManager","description":"Cert-Manager is used by Otomi to automatically create and rotate wildcard TLS certificates for service endpoints. You may bring your own CA, or let Otomi create one for you. If you bring your own trusted wildcard certificate, then cert-manager will not manage this certificate.","sidebar":"mainSidebar"},"apps/drone":{"id":"apps/drone","title":"Drone","description":"Otomi uses Drone to deploy changes from the values repo. As such, it is installed and configured by default. When no source control is configured, Otomi will deploy Gitea as Drone\'s git hosting dependency.","sidebar":"mainSidebar"},"apps/external-dns":{"id":"apps/external-dns","title":"External-DNS","description":"External-dns is required to make public service domains accessible by registering them with Otomi\'s front loadbalancer CNAME or IP address. When it is not enabled (default) Otomi will instead rely on nip.io to create host names for all services.","sidebar":"mainSidebar"},"apps/falco":{"id":"apps/falco","title":"Falco","description":"Falco can be used for thread detection. When turned on"},"apps/gatekeeper":{"id":"apps/gatekeeper","title":"Gatekeeper","description":"Otomi offers Kubernetes security best practices through security constraints defined as OPA policies and enforced by Gatekeeper.","sidebar":"mainSidebar"},"apps/gitea":{"id":"apps/gitea","title":"Gitea","description":"Gitea is a community managed lightweight code hosting solution written in Go. Because Otomi uses Drone to deploy changes to the values repo, it needs a git hosting solution. When no source control is configured, Otomi will deploy Gitea for Drone to target as a git repo. Gitea may be used for other purposes, and is especially useful in combination with Drone as a CI/CD solution. Just like Otomi uses it.","sidebar":"mainSidebar"},"apps/grafana":{"id":"apps/grafana","title":"Grafana","description":"Otomi uses Grafana to visualize Prometheus metrics and Loki logs. Team members are automatically given Editor role, while admins are also given Admin role. It is possible to make configuration changes directly in Grafana, but only to non-conflicting settings. Data sources are preconfigured and must not be edited as changes will be lost when Grafana is redeployed.","sidebar":"mainSidebar"},"apps/harbor":{"id":"apps/harbor","title":"Harbor","description":"Harbor is an open-source registry that secures artifacts with policies and role-based access control, ensures images are scanned and free from vulnerabilities, and signs images as trusted. As a CNCF graduated project, Harbor delivers compliance, performance, and interoperability to help you consistently and securely manage artifacts across cloud-native compute platforms like Kubernetes. (source//goharbor.io/)","sidebar":"mainSidebar"},"apps/ingress-nginx":{"id":"apps/ingress-nginx","title":"NGINX Ingress","description":"Ingress NGINX is the default ingress controller in Otomi and part of the core setup (this means it is not possible use another controller within Otomi).","sidebar":"mainSidebar"},"apps/istio":{"id":"apps/istio","title":"Istio","description":"Since Otomi has security best practices built in, it is designed for intrusion.","sidebar":"mainSidebar"},"apps/jaeger":{"id":"apps/jaeger","title":"Jaeger","description":"Jaeger can be activated by Otomi to gain tracing insights on its network traffic. It runs in anonymous mode and each authenticated user is given the same authorization, allowing them to see everything. In the future this may be limited according to scope such as role and teams.","sidebar":"mainSidebar"},"apps/keycloak":{"id":"apps/keycloak","title":"Keycloak","description":"The SSO login page for Otomi is served by Keycloak. It is used as an identity broker or provider for all Otomi integrated applications. Keycloak is configured with mappers that normalize incoming identities from an IDP to have predictable claims format to be used by Otomi applications.","sidebar":"mainSidebar"},"apps/kiali":{"id":"apps/kiali","title":"Kiali","description":"Kiali can be activated in Otomi to gain observability insights on its network traffic. It runs in anonymous mode and each authenticated user is given the same authorization, allowing them to see everything. In the future this may be limited according to scope such as role and teams."},"apps/knative":{"id":"apps/knative","title":"Knative","description":"Knative can be activated in Otomi to deliver Container-as-a-Service (CaaS) functionality with scale-to-zero possibility. It can be compared to Functions-as-a-service (FaaS) but is container oriented, and takes only one manifest to configure an autoscaling service based on a container image of choice. Otomi uses Istio Virtual Services under the hood to route traffic coming in for a public domain to its backing Knative Service, allowing to set a custom domain.","sidebar":"mainSidebar"},"apps/kubeapps":{"id":"apps/kubeapps","title":"Kubeapps","description":"Kubeapps is a web-based UI for deploying and managing applications in Kubernetes clusters. Kubeapps allows you to:","sidebar":"mainSidebar"},"apps/kubeclarity":{"id":"apps/kubeclarity","title":"Kubeclarity","description":"Kubeclarity can be activated in Otomi to run on-demand scans of running containers in selected namespaces. Otomi also offers Trivy Operator for runtime scanning. Trivy Operator is configured to scan team namespaces only. Kubeclarity is by default configured using Trivy as a scanner and analyser.","sidebar":"mainSidebar"},"apps/loki":{"id":"apps/loki","title":"Loki","description":"Loki aggregates all the container logs from the platform and stores them in a storage endpoint of choice (defaults to PVC). When Otomi is installed in multi-tenancy mode (see here it will split logs from team namespaces and make them available only to team members. Otomi provides shortcuts to selections of logs based on interest. Otomi splits logs per team, installs a dedicated Grafana instance per team and configures authentication for Grafana to allow access for team members only.","sidebar":"mainSidebar"},"apps/minio":{"id":"apps/minio","title":"Minio","description":"Minio can be enabled to provice an in-cluster S3 compatible Object Store service. Minio is by default provisioned to be used by:","sidebar":"mainSidebar"},"apps/prometheus":{"id":"apps/prometheus","title":"Prometheus","description":"Prometheus aggregates all the metrics from the platform and stores them in a storage endpoint of choice (defaults to PVC).","sidebar":"mainSidebar"},"apps/tekton":{"id":"apps/tekton","title":"Tekton","description":"Tekton is used in Otomi for the Builds self-service. When a Build is created, Otomi generates the Tekton Pipeline and Pipelinerun resources. There are 2 types op pipelines:","sidebar":"mainSidebar"},"apps/thanos":{"id":"apps/thanos","title":"Thanos","description":"Thanos can be enabled for multi-cluster long term metrics retention.","sidebar":"mainSidebar"},"apps/trivy":{"id":"apps/trivy","title":"Trivy Operator","description":"Trivy can be enabled to scan all running containers in all team namespaces. When enabled, the team\'s Grafana instance will be configured to provide a dashboard for teams to see all vulnerabilities within their applications.","sidebar":"mainSidebar"},"apps/vault":{"id":"apps/vault","title":"Hashicorp Vault","description":"HashiCorp Vault is a shared application for securely storing and managing secrets. Read more about Vault here.","sidebar":"mainSidebar"},"apps/velero":{"id":"apps/velero","title":"Velero","description":"Velero can be activated for creating backups of PVC\'s and Kubernetes resources.","sidebar":"mainSidebar"},"for-ciso/overview":{"id":"for-ciso/overview","title":"Overview","description":"ISO 27001 controls checklist"},"for-devs/console/apps":{"id":"for-devs/console/apps","title":"Team Apps","description":"The team apps are shared apps on the platform available for teams to use. Click on the app to open the app, or click on the configuration icon to go to the app details:","sidebar":"mainSidebar"},"for-devs/console/builds":{"id":"for-devs/console/builds","title":"Team Builds","description":"A Build in Otomi is a self-service feature for building OCI compliant images based on application source code.","sidebar":"mainSidebar"},"for-devs/console/deploy-changes":{"id":"for-devs/console/deploy-changes","title":"Deploy changes","description":"When a form (build, workload, service, backup, secret) is submitted, Otomi will prepare a commit in the Otomi Values Git repository. When the commit is prepared, the Deploy Changes button in the top of the left menu will become active. To commit your changes, click on the Deploy Changes button.","sidebar":"mainSidebar"},"for-devs/console/projects":{"id":"for-devs/console/projects","title":"Team Projects","description":"A Project in Otomi is a collection of a Build, a Workload and a Service in ONE form.","sidebar":"mainSidebar"},"for-devs/console/secrets":{"id":"for-devs/console/secrets","title":"Team Secrets","description":"Any secret that is created here should have it\'s counterpart in Vault by the same name. Otomi will create kubernetes secrets from those Vault secrets. These can then be used in Otomi Services and Otomi Workloads, as injected env vars, or as file mounts.","sidebar":"mainSidebar"},"for-devs/console/services":{"id":"for-devs/console/services","title":"Team Services","description":"A service in Otomi is a self-service feature for:","sidebar":"mainSidebar"},"for-devs/console/settings":{"id":"for-devs/console/settings","title":"Team Settings","description":"Based on self-service options allowed by the platfrom administrator, team members can change the settings of their team.","sidebar":"mainSidebar"},"for-devs/console/shell":{"id":"for-devs/console/shell","title":"Shell (TTY Console)","description":"The Shell feature allows to start a web based shell in Console with Kube API access. When starting a shell, a dedicated shell instance will be started for the user. The shell includes the following tools:","sidebar":"mainSidebar"},"for-devs/console/shortcuts":{"id":"for-devs/console/shortcuts","title":"Team Shortcuts","description":"The Shortcuts section shows all shortcuts created and available for the team.","sidebar":"mainSidebar"},"for-devs/console/workloads":{"id":"for-devs/console/workloads","title":"Team Workloads","description":"A Workload in Otomi is a self-service feature for:","sidebar":"mainSidebar"},"for-devs/get-started/lab-1":{"id":"for-devs/get-started/lab-1","title":"Prerequisites for getting started","description":"Welcome to Otomi! If you are a developer and are going to use Otomi, this getting started guide is for you. In this first part we are going to make sure everything is ready to get started.","sidebar":"mainSidebar"},"for-devs/get-started/lab-10":{"id":"for-devs/get-started/lab-10","title":"BYO manifest to deploy a workload with Argo CD","description":"Prerequisite: For this lab, Argo CD needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-11":{"id":"for-devs/get-started/lab-11","title":"Configure ArgoCD image updater","description":"In the previous part, you have seen how to use ArgoCD to automatically deploy applications by adding the Kubernetes manifests in to the gitops repo in Gitea. You can also use ArgoCD to deploy Helm charts and automatically update the version of the deployed image.","sidebar":"mainSidebar"},"for-devs/get-started/lab-12":{"id":"for-devs/get-started/lab-12","title":"Deploy a BYO Helm chart","description":"Otomi offers a self-service feature to create 3 types of workloads:","sidebar":"mainSidebar"},"for-devs/get-started/lab-13":{"id":"for-devs/get-started/lab-13","title":"Deploy workloads using Otomi","description":"In the previous 2 parts we have explained how to deploy a workload with a BYO manifest using Kubectl and how to deploy a workload with a BYO manifest using ArgoCD in Otomi. In this part we\'ll deploy a regular workload (a Kubernetes Deployment) using the Otomi Workloads feature.","sidebar":"mainSidebar"},"for-devs/get-started/lab-14":{"id":"for-devs/get-started/lab-14","title":"Deploy serverless workloads","description":"Prerequisite: For this lab, ArgoCD needs to be activated."},"for-devs/get-started/lab-15":{"id":"for-devs/get-started/lab-15","title":"Check policy compliance","description":"Prerequisite: For this lab, Gatekeeper needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-16":{"id":"for-devs/get-started/lab-16","title":"Check for threads","description":"Prerequisite: For this lab, Falco needs to be activated."},"for-devs/get-started/lab-17":{"id":"for-devs/get-started/lab-17","title":"Scan your running containers for vulnerabilities","description":"Prerequisite: For this lab, Trivy needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-18":{"id":"for-devs/get-started/lab-18","title":"Publicly expose your application","description":"When you have deployed your app, you will propably like to expose it publicly. You propably noticed that in the previous part, we created a Kubernetes service of type ClusterIP and not LoadBalancer and also that the Pod(s) created by the deployment have an Istio sidecar. All Pods created in your team will automatically be added to the service mesh. In this part we\'ll create a Service in Otomi to expose your app publicly. When you create a Service, Otomi will then create the Istio virtual service and configure ingress for your application.","sidebar":"mainSidebar"},"for-devs/get-started/lab-19":{"id":"for-devs/get-started/lab-19","title":"Configuring network policies","description":"In some cases you want to explicitly allow access to your application. This can be done by creating network policies. Otomi supports 2 types of network policies:","sidebar":"mainSidebar"},"for-devs/get-started/lab-2":{"id":"for-devs/get-started/lab-2","title":"Access Otomi Console and download the KUBECFG","description":"When you have received the URL of the web UI of Otomi Platform and have a username/password with access permissions, then it\'s time to sign-in","sidebar":"mainSidebar"},"for-devs/get-started/lab-20":{"id":"for-devs/get-started/lab-20","title":"View container logs","description":"Prerequisite: For this lab, Loki and Grafana need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-21":{"id":"for-devs/get-started/lab-21","title":"View container metrics","description":"Prerequisite: For this lab, Prometheus and Grafana need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-22":{"id":"for-devs/get-started/lab-22","title":"Using custom metrics","description":"Prerequisite: For this lab, Prometheus and Grafana need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-23":{"id":"for-devs/get-started/lab-23","title":"Monitoring service availability","description":"When your application is deployed, you would of course like to get an alert when you application (service) is not available anymore. To automatically monitor you applications for availability, Otomi automatically configures a prope to monitor your service.","sidebar":"mainSidebar"},"for-devs/get-started/lab-24":{"id":"for-devs/get-started/lab-24","title":"Create a PostgreSQL database","description":"Otomi by defalt installs the Cloudnative-gp database operator. Teams can use the operator to create their own PostgreSQL databases.","sidebar":"mainSidebar"},"for-devs/get-started/lab-25":{"id":"for-devs/get-started/lab-25","title":"Monitor PostgreSQL databases","description":"If you previously created a database, you\'ll noticed that we did not let the operator create a PodMonitor. The reason of this, is that the PodMonitor requires specific lables to be picked-up by the team\'s own Prometheus. In this lab we\'ll create a custom PodMonitor and create a dashboard in the team\'s own Grafana.","sidebar":"mainSidebar"},"for-devs/get-started/lab-3":{"id":"for-devs/get-started/lab-3","title":"Create a private Git repo","description":"As a developer you\'ll need a Git repository for your code. Most organizations will probably have a central code repository like Gitlab, or use Github. But if you don\'t, Otomi has you covered. Otomi includes a complete self-hosted Git solution called Gitea.","sidebar":"mainSidebar"},"for-devs/get-started/lab-4":{"id":"for-devs/get-started/lab-4","title":"Create a CI pipeline","description":"Kubernetes is a container orchestrator, so we need to create container images that we can deploy. Next to providing a Git service. Otomi also has a complete CI solution called Drone integrated. You can use Drone to create and run CI pipelines to build images and push them to your private image registry (Harbor).","sidebar":"mainSidebar"},"for-devs/get-started/lab-5":{"id":"for-devs/get-started/lab-5","title":"Push your container images","description":"Prerequisite: For this lab, Harbor needs to be activated and the cluster needs to be configured with trusted certificates (like Let\'s Encrypt using production certificate).","sidebar":"mainSidebar"},"for-devs/get-started/lab-6":{"id":"for-devs/get-started/lab-6","title":"Build images from application source","description":"Prerequisite: For this lab, Harbor and Tekton need to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-7":{"id":"for-devs/get-started/lab-7","title":"Scan your images for vulnerabilities","description":"When your team is using Harbor for private image registries, you can use Trivy to automatically scan your images on push. This is not enabled by default. Ask your platform administrator to turn this on for your project in Harbor. When enabled, you can see the results of the scans by following these steps:","sidebar":"mainSidebar"},"for-devs/get-started/lab-8":{"id":"for-devs/get-started/lab-8","title":"Create secrets","description":"Prerequisite: For this lab, Hashicorp Vault needs to be activated.","sidebar":"mainSidebar"},"for-devs/get-started/lab-9":{"id":"for-devs/get-started/lab-9","title":"Deploy your application","description":"Now that you have access to the team namespace and have pushed your image to Harbor, you can now deploy your application."},"for-devs/get-started/overview":{"id":"for-devs/get-started/overview","title":"Get started with Otomi for Developers","description":"Welcome to Otomi! If you are a developer and are going to use Otomi Platform, these getting started labs are for you. Step by step we\'ll guide you in using Otomi to deploy and manage your containerized applications. The getting started with Otomi for developers contains a set of labs to cover the most common developer activities.","sidebar":"mainSidebar"},"for-ops/cli/apply":{"id":"for-ops/cli/apply","title":"otomi apply","description":"otomi apply [options]","sidebar":"mainSidebar"},"for-ops/cli/bash":{"id":"for-ops/cli/bash","title":"otomi bash","description":"otomi bash","sidebar":"mainSidebar"},"for-ops/cli/bootstrap":{"id":"for-ops/cli/bootstrap","title":"otomi bootstrap","description":"otomi bootstrap [options]","sidebar":"mainSidebar"},"for-ops/cli/check-policies":{"id":"for-ops/cli/check-policies","title":"check-policies","description":"otomi check-policies [options]","sidebar":"mainSidebar"},"for-ops/cli/commit":{"id":"for-ops/cli/commit","title":"otomi commit","description":"otomi commit [options]","sidebar":"mainSidebar"},"for-ops/cli/decrypt":{"id":"for-ops/cli/decrypt","title":"otomi decrypt","description":"otomi decrypt [options]","sidebar":"mainSidebar"},"for-ops/cli/deploying":{"id":"for-ops/cli/deploying","title":"Using Otomi CLI","description":"1. Initialize a values repo","sidebar":"mainSidebar"},"for-ops/cli/destroy":{"id":"for-ops/cli/destroy","title":"otomi destroy","description":"otomi destroy [options]","sidebar":"mainSidebar"},"for-ops/cli/diff":{"id":"for-ops/cli/diff","title":"otomi diff","description":"otomi diff [options]","sidebar":"mainSidebar"},"for-ops/cli/encrypt":{"id":"for-ops/cli/encrypt","title":"otomi encrypt","description":"otomi encrypt [files...] [options]","sidebar":"mainSidebar"},"for-ops/cli/installation":{"id":"for-ops/cli/installation","title":"Installing and using Otomi CLI","description":"Prerequisites","sidebar":"mainSidebar"},"for-ops/cli/known-issues":{"id":"for-ops/cli/known-issues","title":"Known Issues","description":"The otomi (diff|apply|sync|template) commands are delegated to helmfile, which in turn delegates the deployment work to helm. Sometimes it is not clear wether the issue is from Helm or Helmfile, so we will address them together in this section.","sidebar":"mainSidebar"},"for-ops/cli/lint":{"id":"for-ops/cli/lint","title":"otomi lint","description":"otomi lint [options]","sidebar":"mainSidebar"},"for-ops/cli/pull":{"id":"for-ops/cli/pull","title":"otomi pull","description":"otomi pull [options]","sidebar":"mainSidebar"},"for-ops/cli/rotate-keys":{"id":"for-ops/cli/rotate-keys","title":"otomi rotate-keys","description":"otomi rotate-keys [options]","sidebar":"mainSidebar"},"for-ops/cli/status":{"id":"for-ops/cli/status","title":"otomi status","description":"otomi status [options]","sidebar":"mainSidebar"},"for-ops/cli/sync":{"id":"for-ops/cli/sync","title":"otomi sync","description":"otomi sync [options]","sidebar":"mainSidebar"},"for-ops/cli/template":{"id":"for-ops/cli/template","title":"otomi template","description":"otomi template [options]","sidebar":"mainSidebar"},"for-ops/cli/test":{"id":"for-ops/cli/test","title":"otomi test","description":"otomi test [options]","sidebar":"mainSidebar"},"for-ops/cli/validate-templates":{"id":"for-ops/cli/validate-templates","title":"otomi validate-templates","description":"otomi validate-templates [options]","sidebar":"mainSidebar"},"for-ops/cli/validate-values":{"id":"for-ops/cli/validate-values","title":"otomi validate-values","description":"otomi validate-values [options]","sidebar":"mainSidebar"},"for-ops/cli/values":{"id":"for-ops/cli/values","title":"otomi values","description":"otomi values [options]","sidebar":"mainSidebar"},"for-ops/cli/x":{"id":"for-ops/cli/x","title":"otomi x","description":"otomi x","sidebar":"mainSidebar"},"for-ops/console/apps":{"id":"for-ops/console/apps","title":"Platform - Apps","description":"The apps section lists all apps available.","sidebar":"mainSidebar"},"for-ops/console/backups":{"id":"for-ops/console/backups","title":"Platform - Backups","description":"To enable this feature, first make sure Velero is activated.","sidebar":"mainSidebar"},"for-ops/console/builds":{"id":"for-ops/console/builds","title":"Platform - Builds","description":"To enable this feature, first make sure Harbor and Tekton are activated. To be able to push images to Harbor, Otomi needs to be configured with a DNS and trusted certificates (Lets encrypt with production certificates).","sidebar":"mainSidebar"},"for-ops/console/clusters":{"id":"for-ops/console/clusters","title":"Platform - Clusters","description":"All known Otomi clusters are listed here. Clusters can be sorted based on:","sidebar":"mainSidebar"},"for-ops/console/deploy-changes":{"id":"for-ops/console/deploy-changes","title":"Deploy changes","description":"When a change has been made, by pressing Submit, the Deploy Changes button will light up to deploy the changes you have made in the console. This will create a commit of the changes to the values repository in Gitea and trigger the Drone pipeline run."},"for-ops/console/overview":{"id":"for-ops/console/overview","title":"Overview","description":"Otomi Console","sidebar":"mainSidebar"},"for-ops/console/policies":{"id":"for-ops/console/policies","title":"Platform - Policies","description":"To enable this feature, first make sure OPA/Gatekeeper is activated.","sidebar":"mainSidebar"},"for-ops/console/projects":{"id":"for-ops/console/projects","title":"Projects","description":"A Project in Otomi is a collection of a Build, a Workload and a Service in ONE form. When a user creates a project, the name of the project will be used for all created tasks (build, workload, service).","sidebar":"mainSidebar"},"for-ops/console/secrets":{"id":"for-ops/console/secrets","title":"Platform - Secrets","description":"To enable this feature, first make sure Hashicorp Vault is activated.","sidebar":"mainSidebar"},"for-ops/console/services":{"id":"for-ops/console/services","title":"Platform - Services","description":"All known Services on the platform are listed here. Services can be sorted based on:","sidebar":"mainSidebar"},"for-ops/console/settings/alerts":{"id":"for-ops/console/settings/alerts","title":"Platform settings","description":"Alerts","sidebar":"mainSidebar"},"for-ops/console/settings/azure":{"id":"for-ops/console/settings/azure","title":"Platform settings","description":"Azure","sidebar":"mainSidebar"},"for-ops/console/settings/backup":{"id":"for-ops/console/settings/backup","title":"Platform settings","description":"Backup","sidebar":"mainSidebar"},"for-ops/console/settings/cluster":{"id":"for-ops/console/settings/cluster","title":"Platform settings","description":"Cluster","sidebar":"mainSidebar"},"for-ops/console/settings/co-monitoring":{"id":"for-ops/console/settings/co-monitoring","title":"Platform settings","description":"Co-Monitoring","sidebar":"mainSidebar"},"for-ops/console/settings/dns":{"id":"for-ops/console/settings/dns","title":"Platform settings","description":"DNS","sidebar":"mainSidebar"},"for-ops/console/settings/ingress":{"id":"for-ops/console/settings/ingress","title":"Platform settings","description":"Ingress","sidebar":"mainSidebar"},"for-ops/console/settings/key-management":{"id":"for-ops/console/settings/key-management","title":"Platform settings","description":"Key management","sidebar":"mainSidebar"},"for-ops/console/settings/oidc":{"id":"for-ops/console/settings/oidc","title":"Platform settings","description":"OIDC","sidebar":"mainSidebar"},"for-ops/console/settings/otomi":{"id":"for-ops/console/settings/otomi","title":"Platform settings","description":"Otomi","sidebar":"mainSidebar"},"for-ops/console/settings/smtp":{"id":"for-ops/console/settings/smtp","title":"Platform settings","description":"SMTP","sidebar":"mainSidebar"},"for-ops/console/shell":{"id":"for-ops/console/shell","title":"Shell","description":"The Shell feature allows to start a web based shell in Console with Kube API access. When starting a shell, a dedicated shell instance will be started for the user. The shell includes the following tools:","sidebar":"mainSidebar"},"for-ops/console/shortcuts":{"id":"for-ops/console/shortcuts","title":"Platform - Shortcuts","description":"The Shortcuts section shows all shortcuts created and available on the platform for users with the otomi-admin role.","sidebar":"mainSidebar"},"for-ops/console/teams":{"id":"for-ops/console/teams","title":"Platform - Teams","description":"- Teams are tenants on the platform to support Development/DevOps teams, projects or even DTAP","sidebar":"mainSidebar"},"for-ops/console/workloads":{"id":"for-ops/console/workloads","title":"Platform - Workloads","description":"To enable this feature, first make sure ArgoCD is activated.","sidebar":"mainSidebar"},"for-ops/how-to/core-only":{"id":"for-ops/how-to/core-only","title":"Use Otomi Core only","description":"Otomi by default installs Gitea, Drone, Otomi API and Otomi Console. Otomi Console is the self-service UI and uses Otomi API to generate validated configuration code. This configuration code is then committed to Gitea (in the values repository), which will trigger teh pre-configured Drone pipeline to apply the changes.","sidebar":"mainSidebar"},"for-ops/how-to/create-and-restore-backups":{"id":"for-ops/how-to/create-and-restore-backups","title":"Create/Restore backups","description":"When Velero is activated on the platform level, platform admins can create backups of Persistent Volumes (PVs) in Team namespaces using Otomi Console. When creating backups using Otomi Console, a Velero schedule resource is created that will create the backup at a specified time, defined by a Cron expression.","sidebar":"mainSidebar"},"for-ops/how-to/ingress-classes":{"id":"for-ops/how-to/ingress-classes","title":"Use private ingress class","description":"When Otomi is installed, exposure (ingress) for all services (included exposure for platform services) is handeled by the default platform ingress class using a public (cloud) load balancer. Otomi offers the option to use multiple ingress classes. Each class get a dedicated ingress controller. In case of security requirements, where platform services are not allowed to be exposed publicly, the default platform class can be configured to use a private load balancer instead of a public one. Additional (public) ingress classes can be created to expose team (application) services.","sidebar":"mainSidebar"},"for-ops/how-to/install-with-dns":{"id":"for-ops/how-to/install-with-dns","title":"Install Otomi with DNS","description":"Route53","sidebar":"mainSidebar"},"for-ops/how-to/switch-to-dns":{"id":"for-ops/how-to/switch-to-dns","title":"Switch to use DNS","description":"When Otomi is installed with minimal values, a custom CA is generated and Otomi uses nip.io for host names. It is possible to switch from nip.io to using a DNS zone after installing Otomi initially without DNS. To switch from nip.io to a DNS zone, follow the instructions as described below."},"for-ops/how-to/use-team-admin":{"id":"for-ops/how-to/use-team-admin","title":"Use team-admin","description":"When Otomi is installed, by default a team called team-admin is created. The Admin Team is no regular team. This team for instance has no apps. Instead the admin needs to use the platform apps to see logs and metrics of workloads deployed in the team-admin namespace.","sidebar":"mainSidebar"},"for-ops/sre/daily":{"id":"for-ops/sre/daily","title":"SRE Daily Routine","description":"As an SRE you would like to keep your daily tasks to a minimum and be automatically informed on issues. Otomi offers the following tooling to automate this:","sidebar":"mainSidebar"},"for-ops/sre/overview":{"id":"for-ops/sre/overview","title":"SRE Overview","description":"Otomi is a set of functions built on top of a suite of pre-configured and integrated open source applications. Instead of selecting, configuring, and integrating all the parts that are needed to securely manage containerized applications in multi- and hybrid environments, Otomi offers all required parts in a single package. Otomi can be seen as any other Kubernetes application or add-on, with the difference that Otomi is pre-configured and offers a higher abstraction of configuration for all the integrated solutions. All integrated applications can however be used freely, meaning that a user can benefit from the pre-configuration to start using the offered applications.","sidebar":"mainSidebar"},"for-ops/sre/troubleshooting":{"id":"for-ops/sre/troubleshooting","title":"SRE Troubleshooting Checklist","description":"Pods not starting","sidebar":"mainSidebar"},"for-ops/sre/upgrades":{"id":"for-ops/sre/upgrades","title":"Upgrades","description":"Introduction","sidebar":"mainSidebar"},"get-started/activation":{"id":"get-started/activation","title":"Activation steps","description":"Follow the steps below to activate Otomi after initial installation.","sidebar":"mainSidebar"},"get-started/chart":{"id":"get-started/chart","title":"Install from chart","description":"Use Helm to install Otomi."},"get-started/installation":{"id":"get-started/installation","title":"Installation","description":"Install Otomi with Helm","sidebar":"mainSidebar"},"get-started/optional":{"id":"get-started/optional","title":"Optional configuration","description":"You can optionally configure Otomi to use an external IDP (Azure AD), use an external Key Management Service (KMS) provider for SOPS and use a DNS zone in combination with LetsEncrpt certificates. Below you can find detailed instructions on how to set up Azure AD as an external IDP and configure KMS. We will soon add more instructions for other IDPs, such as Amazon Incognito, Google Identity, and Okta."},"get-started/prerequisites":{"id":"get-started/prerequisites","title":"Prerequisites","description":"Client binaries","sidebar":"mainSidebar"},"tutorials/overview":{"id":"tutorials/overview","title":"Tutorial Overview","description":"This section contains tutorials for more advanced installation scenario\'s."},"tutorials/tutorial-1":{"id":"tutorials/tutorial-1","title":"Installing Otomi","description":"To go through the tutorials, you first need to install Otomi on a running Kubernetes cluster."},"tutorials/tutorial-10":{"id":"tutorials/tutorial-10","title":"Creating a micro service architecture","description":"In this tutorial we are going to deploy multiple services from different teams and expose them using a shared domain, but each on their own path. We will use on-the-fly Knative services for speed and simplicity."},"tutorials/tutorial-2":{"id":"tutorials/tutorial-2","title":"Creating teams","description":"In this tutorial, we are going to create a Team in Otomi. Teams in Otomi serve the following purpose:"},"tutorials/tutorial-3":{"id":"tutorials/tutorial-3","title":"Activating tools","description":"Core Apps"},"tutorials/tutorial-4":{"id":"tutorials/tutorial-4","title":"Build, tag and push an image to Harbor","description":"When Otomi is installed without using Let\'s Encrypt production certificates, make sure you download the CA.crt, add it to your Keychain and restarted Docker."},"tutorials/tutorial-5":{"id":"tutorials/tutorial-5","title":"Create a Workload","description":"In his tutorial, we are going to create a Workload in Otomi."},"tutorials/tutorial-6":{"id":"tutorials/tutorial-6","title":"Create a Service","description":"In his tutorial, we are going to create a Service in Otomi to publicly expose the ClusterIP service of the Workload we deployed in the previous tutorial."},"tutorials/tutorial-7":{"id":"tutorials/tutorial-7","title":"Using Knative","description":"In this lab, we are going to:"},"tutorials/tutorial-8":{"id":"tutorials/tutorial-8","title":"Using secrets","description":"In his tutorial, you are going to:"},"tutorials/tutorial-9":{"id":"tutorials/tutorial-9","title":"Configuring network policies","description":"In this tutorial we are going to deploy a multi tier web application, called guestbook, register the 3 K8s services in Otomi and configure public access to the frontend service. Next, we will turn on the Network policies option for the team."},"tutorials/tutorial-create-byo-ksvc":{"id":"tutorials/tutorial-create-byo-ksvc","title":"Create a Knative service","description":"In this tutorial, you are going to deploy the image you build, tagged and pushed to harbor in the previous tutorial by creating a Knative service."},"tutorials/tutorial-create-byo-svc":{"id":"tutorials/tutorial-create-byo-svc","title":"Create a Kubernetes service","description":"In this tutorial, we are going to deploy the image we pushed to harbor in the previous tutorial, by creating a Kubernetes Deployment and Service."},"tutorials/tutorial-create-otomi-ksvc":{"id":"tutorials/tutorial-create-otomi-ksvc","title":"Create and expose a Knative service with Otomi","description":"In his tutorial, we are going to create a Knative service with Otomi Console and publicly expose it."},"tutorials/tutorial-use-secrets":{"id":"tutorials/tutorial-use-secrets","title":"Use secrets in Kubernetes","description":"In his tutorial, you are going to use the secret created in Hashicorp Vault and added to Kubernetes using the Otomi Secrets feature in a Kubernetes deployment."}}}')}}]); \ No newline at end of file diff --git a/assets/js/a3d159d0.54c2f9ba.js b/assets/js/a3d159d0.54c2f9ba.js deleted file mode 100644 index 9314ba102..000000000 --- a/assets/js/a3d159d0.54c2f9ba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[1696],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var i=n(7294);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(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,b=d["".concat(s,".").concat(m)]||d[m]||c[m]||r;return n?i.createElement(b,l(l({ref:t},u),{},{components:n})):i.createElement(b,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,l=new Array(r);l[0]=d;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const r={slug:"lab-6",title:"Build images from application source",sidebar_label:"Build images with Otomi"},l=void 0,o={unversionedId:"for-devs/get-started/lab-6",id:"for-devs/get-started/lab-6",title:"Build images from application source",description:"Prerequisite: For this lab, Harbor and Tekton need to be activated.",source:"@site/docs/for-devs/get-started/lab-6.md",sourceDirName:"for-devs/get-started",slug:"/for-devs/get-started/lab-6",permalink:"/docs/for-devs/get-started/lab-6",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/tree/main/docs/for-devs/get-started/lab-6.md",tags:[],version:"current",frontMatter:{slug:"lab-6",title:"Build images from application source",sidebar_label:"Build images with Otomi"},sidebar:"mainSidebar",previous:{title:"Push images",permalink:"/docs/for-devs/get-started/lab-5"},next:{title:"Scan images",permalink:"/docs/for-devs/get-started/lab-7"}},s={},p=[],u={toc:p};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,i.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Prerequisite: For this lab, Harbor and Tekton need to be activated.")),(0,a.kt)("p",null,"When your team is using Harbor for private image registries and Tekton is enabled, you can build images from source using pre-configured Tekton pipelines and buildpacks from ",(0,a.kt)("a",{parentName:"p",href:"https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/"},"paketo")," to build images from application source."),(0,a.kt)("p",null,"In this lab, you are going to create a build, using the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-petclinic"},"Spring Pet Clinic sample app")," and buildpacks. When using the buildpacks option, Otomi uses buildpacks to build an image based on application source code without using a Dockerfile."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"In the right menu, click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Build")),(0,a.kt)("li",{parentName:"ol"},"Click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Create Build")),(0,a.kt)("li",{parentName:"ol"},"Fill in the name ",(0,a.kt)("inlineCode",{parentName:"li"},"petclinic")," for your build and a tag (default is tag is latest)"),(0,a.kt)("li",{parentName:"ol"},"Choose ",(0,a.kt)("inlineCode",{parentName:"li"},"Buildpacks")),(0,a.kt)("li",{parentName:"ol"},"In the ",(0,a.kt)("inlineCode",{parentName:"li"},"Application source")," section, fill in the following:")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"RepoURL: ",(0,a.kt)("inlineCode",{parentName:"li"},"https://github.com/spring-projects/spring-petclinic")),(0,a.kt)("li",{parentName:"ul"},"revision: ",(0,a.kt)("inlineCode",{parentName:"li"},"82cb521d636b282340378d80a6307a08e3d4a4c4"))),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Click ",(0,a.kt)("inlineCode",{parentName:"li"},"Submit"))),(0,a.kt)("p",null,"To see the status of the build, open a Shell (in the right menu in the Console) and run ",(0,a.kt)("inlineCode",{parentName:"p"},"k9s"),". You will now see all the pods in your team's namespace. 2 new pods will start and run the build pipeline tasks."),(0,a.kt)("p",null,"When the build is ready (the 2 build pods have the status ",(0,a.kt)("inlineCode",{parentName:"p"},"completed"),"), you will see the image in Harbor:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Open Harbor"),(0,a.kt)("li",{parentName:"ol"},"Click on the project of your team. Here you will see all the registries of the team, including the registry of the new build image")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"harbor-projects",src:n(4841).Z,width:"3060",height:"1022"})),(0,a.kt)("p",null,"When using the Build feature in Otomi, a Tekton Pipeline is created and the pipline is executed only once using a Tekton Pipelinerun. To run the build again using Otomi Console, follow these steps:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Change the tag of the build to ",(0,a.kt)("inlineCode",{parentName:"li"},"1.0.0")),(0,a.kt)("li",{parentName:"ol"},"Submit changes")),(0,a.kt)("p",null,"To re-build the image using the same tag, restart the build pipeline using the Tekton cli in the Shell:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Start a shell in Otomi Console")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Get the name of the pipeline"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get pipelines\nNAME AGE\nbuildpacks-build-petclinic 5m10s\n")),(0,a.kt)("ol",{start:3},(0,a.kt)("li",{parentName:"ol"},"Get the name of the pipelinerun:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get pipelineruns\nNAME SUCCEEDED REASON STARTTIME COMPLETIONTIME\nbuildpacks-build-petclinic-latest False Failed 5m18s 4m27s\n")),(0,a.kt)("ol",{start:4},(0,a.kt)("li",{parentName:"ol"},"Start the pipeline using the pipelinerun:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"tkn pipeline start buildpacks-build-petclinic --use-pipelinerun buildpacks-build-petclinic-latest\nPipelineRun started: buildpacks-build-petclinic-latest-j5mmt\n")),(0,a.kt)("ol",{start:5},(0,a.kt)("li",{parentName:"ol"},"In order to track the PipelineRun progress run:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"tkn pipelinerun logs buildpacks-build-petclinic-latest-j5mmt -f\n")))}c.isMDXComponent=!0},4841:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/see-build-harbor-2f494c446cd55265ff5758d1690d7fc3.png"}}]); \ No newline at end of file diff --git a/assets/js/a3d159d0.6552508a.js b/assets/js/a3d159d0.6552508a.js new file mode 100644 index 000000000..39d781147 --- /dev/null +++ b/assets/js/a3d159d0.6552508a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[1696],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var i=n(7294);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(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,b=d["".concat(s,".").concat(m)]||d[m]||c[m]||r;return n?i.createElement(b,l(l({ref:t},u),{},{components:n})):i.createElement(b,l({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,l=new Array(r);l[0]=d;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const r={slug:"lab-6",title:"Build images from application source",sidebar_label:"Build images with Otomi"},l=void 0,o={unversionedId:"for-devs/get-started/lab-6",id:"for-devs/get-started/lab-6",title:"Build images from application source",description:"Prerequisite: For this lab, Harbor and Tekton need to be activated.",source:"@site/docs/for-devs/get-started/lab-6.md",sourceDirName:"for-devs/get-started",slug:"/for-devs/get-started/lab-6",permalink:"/docs/for-devs/get-started/lab-6",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/tree/main/docs/for-devs/get-started/lab-6.md",tags:[],version:"current",frontMatter:{slug:"lab-6",title:"Build images from application source",sidebar_label:"Build images with Otomi"},sidebar:"mainSidebar",previous:{title:"Push images",permalink:"/docs/for-devs/get-started/lab-5"},next:{title:"Trigger builds",permalink:"/docs/for-devs/get-started/lab-26"}},s={},p=[],u={toc:p};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,i.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Prerequisite: For this lab, Harbor and Tekton need to be activated.")),(0,a.kt)("p",null,"When your team is using Harbor for private image registries and Tekton is enabled, you can build images from source using pre-configured Tekton pipelines and buildpacks from ",(0,a.kt)("a",{parentName:"p",href:"https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/"},"paketo")," to build images from application source."),(0,a.kt)("p",null,"In this lab, you are going to create a build, using the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-petclinic"},"Spring Pet Clinic sample app")," and buildpacks. When using the buildpacks option, Otomi uses buildpacks to build an image based on application source code without using a Dockerfile."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"In the right menu, click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Build")),(0,a.kt)("li",{parentName:"ol"},"Click on ",(0,a.kt)("inlineCode",{parentName:"li"},"Create Build")),(0,a.kt)("li",{parentName:"ol"},"Fill in the name ",(0,a.kt)("inlineCode",{parentName:"li"},"petclinic")," for your build and a tag (default is tag is latest)"),(0,a.kt)("li",{parentName:"ol"},"Choose ",(0,a.kt)("inlineCode",{parentName:"li"},"Buildpacks")),(0,a.kt)("li",{parentName:"ol"},"In the ",(0,a.kt)("inlineCode",{parentName:"li"},"Application source")," section, fill in the following:")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"RepoURL: ",(0,a.kt)("inlineCode",{parentName:"li"},"https://github.com/spring-projects/spring-petclinic")),(0,a.kt)("li",{parentName:"ul"},"revision: ",(0,a.kt)("inlineCode",{parentName:"li"},"82cb521d636b282340378d80a6307a08e3d4a4c4"))),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Click ",(0,a.kt)("inlineCode",{parentName:"li"},"Submit"))),(0,a.kt)("p",null,"To see the status of the build, open a Shell (in the right menu in the Console) and run ",(0,a.kt)("inlineCode",{parentName:"p"},"k9s"),". You will now see all the pods in your team's namespace. 2 new pods will start and run the build pipeline tasks."),(0,a.kt)("p",null,"When the build is ready (the 2 build pods have the status ",(0,a.kt)("inlineCode",{parentName:"p"},"completed"),"), you will see the image in Harbor:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Open Harbor"),(0,a.kt)("li",{parentName:"ol"},"Click on the project of your team. Here you will see all the registries of the team, including the registry of the new build image")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"harbor-projects",src:n(4841).Z,width:"3060",height:"1022"})),(0,a.kt)("p",null,"When using the Build feature in Otomi, a Tekton Pipeline is created and the pipline is executed only once using a Tekton Pipelinerun. To run the build again using Otomi Console, follow these steps:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Change the tag of the build to ",(0,a.kt)("inlineCode",{parentName:"li"},"1.0.0")),(0,a.kt)("li",{parentName:"ol"},"Submit changes")),(0,a.kt)("p",null,"To re-build the image using the same tag, restart the build pipeline using the Tekton cli in the Shell:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Start a shell in Otomi Console")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Get the name of the pipeline"))),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get pipelines\nNAME AGE\nbuildpacks-build-petclinic 5m10s\n")),(0,a.kt)("ol",{start:3},(0,a.kt)("li",{parentName:"ol"},"Get the name of the pipelinerun:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl get pipelineruns\nNAME SUCCEEDED REASON STARTTIME COMPLETIONTIME\nbuildpacks-build-petclinic-latest False Failed 5m18s 4m27s\n")),(0,a.kt)("ol",{start:4},(0,a.kt)("li",{parentName:"ol"},"Start the pipeline using the pipelinerun:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"tkn pipeline start buildpacks-build-petclinic --use-pipelinerun buildpacks-build-petclinic-latest\nPipelineRun started: buildpacks-build-petclinic-latest-j5mmt\n")),(0,a.kt)("ol",{start:5},(0,a.kt)("li",{parentName:"ol"},"In order to track the PipelineRun progress run:")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"tkn pipelinerun logs buildpacks-build-petclinic-latest-j5mmt -f\n")))}c.isMDXComponent=!0},4841:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/see-build-harbor-2f494c446cd55265ff5758d1690d7fc3.png"}}]); \ No newline at end of file diff --git a/assets/js/b0500dc6.54fdf353.js b/assets/js/b0500dc6.196d75df.js similarity index 98% rename from assets/js/b0500dc6.54fdf353.js rename to assets/js/b0500dc6.196d75df.js index ff3b6812e..4ca6701a5 100644 --- a/assets/js/b0500dc6.54fdf353.js +++ b/assets/js/b0500dc6.196d75df.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[8185],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var a=n(7294);function o(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(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,h=m["".concat(l,".").concat(d)]||m[d]||p[d]||r;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var a=n(7462),o=(n(7294),n(3905));const r={slug:"multi-tenancy",title:"Multi-tenancy",sidebar_label:"Multi-tenancy"},i=void 0,s={unversionedId:"use-cases/multi-tenancy",id:"use-cases/multi-tenancy",title:"Multi-tenancy",description:"Introduction",source:"@site/product/use-cases/multi-tenancy.md",sourceDirName:"use-cases",slug:"/use-cases/multi-tenancy",permalink:"/product/use-cases/multi-tenancy",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/multi-tenancy.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"multi-tenancy",title:"Multi-tenancy",sidebar_label:"Multi-tenancy"},sidebar:"mainSidebar",previous:{title:"Adoption Framework",permalink:"/product/use-cases/adoption-framework"},next:{title:"CI/CD",permalink:"/product/use-cases/ci-cd"}},l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Multi-tenancy in Otomi",id:"multi-tenancy-in-otomi",level:2},{value:"Why multi-tenancy in Otomi?",id:"why-multi-tenancy-in-otomi",level:2},{value:"Prevent cluster sprawl",id:"prevent-cluster-sprawl",level:3},{value:"Fast onboarding of multiple tenants",id:"fast-onboarding-of-multiple-tenants",level:3}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,'Multi-tenant Kubernetes clusters are shared by multiple users and/or workloads which are referred to as "tenants". Operators most commonly implement resource isolation in Kubernetes, using namespaces and resource quota.'),(0,o.kt)("p",null,"The most common use cases for implementing multi-tenancy are:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/security/multi-tenancy/#multiple-teams"},"Multiple teams")," (within an organization) share a single cluster"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/security/multi-tenancy/#multiple-customers"},"Multiple customers")," share a single cluster")),(0,o.kt)("p",null,"Probably the most known tools to implement multi-tenancy are ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/clastix/capsule"},"Capsule")," and ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/loft-sh/kiosk"},"Kiosk"),". But these tools only implement multi-tenancy on cluster API level. What they don't offer is multi-tenant and role based access to shared tools on the cluster like Harbor, Vault, Git, and ArgoCD. They also don't provide isolation for container logs and custom metrics."),(0,o.kt)("p",null,"So what if you would like to offer teams or customers not only access to the Kubernetes API, but also to (automatically provisioned) access to a Git repo, a private docker registry, a space in Vault to create and manage secrets, ArgoCD, a private Prometheus instance, isolated log aggregation? This is where Otomi steps in."),(0,o.kt)("h2",{id:"multi-tenancy-in-otomi"},"Multi-tenancy in Otomi"),(0,o.kt)("p",null,"Otomi goes a step higher up in the stack. Otomi does not only provide multi-tenancy on the K8s API level, but also for shared tools on the cluster. "),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"multi-tenancy",src:n(1998).Z,width:"2025",height:"1465"})),(0,o.kt)("p",null,"When multi-tenancy in Otomi is activated (which is optional), Otomi will support the following features:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Teams are provided with a dedicated Prometheus instance for custom metrics (for metrics that should not be accessible for other tenants)"),(0,o.kt)("li",{parentName:"ol"},"Teams are provided with a dedicated Grafana instance configured with authorization, allowing only authenticated tenant members to access tenant dashboards"),(0,o.kt)("li",{parentName:"ol"},"Container logs are separated in Loki combined with authorization, allowing only authenticated tenant members access to the tenants container logs"),(0,o.kt)("li",{parentName:"ol"},"When Harbor is enabled, tenants will get access to a tenant project, allowing only authenticated tenant members to access tenant registries"),(0,o.kt)("li",{parentName:"ol"},"When Vault is enabled, tenant will get access to a space in Vault, allowing only authenticated tenant members access to tenant secrets"),(0,o.kt)("li",{parentName:"ol"},"When ArgoCD is enabled, tenants can only see the tenants ArgoCD applications created by Otomi"),(0,o.kt)("li",{parentName:"ol"},"Tenants will get access to Gitea and can create their own Git repositories"),(0,o.kt)("li",{parentName:"ol"},"Tenant namespaces are by default isolated for ingress and egress network traffic"),(0,o.kt)("li",{parentName:"ol"},"Tenants can allow other tenants to access their services"),(0,o.kt)("li",{parentName:"ol"},"Tenant services that are publicly exposed can be configured with OIDC, only allowing tenant members to access the exposed services")),(0,o.kt)("h2",{id:"why-multi-tenancy-in-otomi"},"Why multi-tenancy in Otomi?"),(0,o.kt)("h3",{id:"prevent-cluster-sprawl"},"Prevent cluster sprawl"),(0,o.kt)("p",null,"As companies look to further harness the power of cloud-native, they are adopting container technologies at rapid speed, increasing the number of clusters and workloads. As the number of Kubernetes clusters grows, this is creating increased work for Platform teams. When it comes to patching security vulnerabilities or upgrading clusters, teams are doing five times the amount of work."),(0,o.kt)("p",null,"With Otomi you can support multi-tenancy, allowing multiple tenants (like multiple development teams) to work independently on the same cluster, while sharing all the tools. Now you only have to deploy a single development cluster to support multiple development teams. This prevents you from Kubernetes cluster sprawl."),(0,o.kt)("h3",{id:"fast-onboarding-of-multiple-tenants"},"Fast onboarding of multiple tenants"),(0,o.kt)("p",null,"When a new project starts, or when a new development team would like to start using Kubernetes, onboarding usually takes a lot of time. It's not only about providing development teams access to a Kubernetes namespace. No, developers also need access to an image registry, container logs, container metrics, alerts, secrets stores, container vulnerability reports and policy compliance reports."),(0,o.kt)("p",null,"With Otomi you can onboard development teams (tenants) in just a couple of minutes, allowing them to login to the self-service portal and:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Get access to a private image registry"),(0,o.kt)("li",{parentName:"ul"},"Download the Docker login credentials to get access to their private image registry"),(0,o.kt)("li",{parentName:"ul"},"Build OCI-compliant images from application code"),(0,o.kt)("li",{parentName:"ul"},"Deploy images (stored in the private registry) using the Otomi workloads feature"),(0,o.kt)("li",{parentName:"ul"},"Get access to pre-configured dashboards to see container metrics, policy violations, detected threads in containers and detected vulnerabilities in containers"),(0,o.kt)("li",{parentName:"ul"},"Configure ingress and network policies"),(0,o.kt)("li",{parentName:"ul"},"Configure HTTP response headers"),(0,o.kt)("li",{parentName:"ul"},"Configure CNAMEs"),(0,o.kt)("li",{parentName:"ul"},"Get access to Vault to create and manage secrets"),(0,o.kt)("li",{parentName:"ul"},"Use secrets for ingress or workloads")),(0,o.kt)("p",null,"When a team already has a code repo with a Dockderfile, they can build, deploy and expose this app within minutes after they have been onboarded onto the platform."))}p.isMDXComponent=!0},1998:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/multi-tenancy-6d20d20cfd471ce025aa59ca8b3498bf.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[8185],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var a=n(7294);function o(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(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=c(n),d=o,h=m["".concat(l,".").concat(d)]||m[d]||p[d]||r;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var a=n(7462),o=(n(7294),n(3905));const r={slug:"multi-tenancy",title:"Multi-tenancy",sidebar_label:"Multi-tenancy"},i=void 0,s={unversionedId:"use-cases/multi-tenancy",id:"use-cases/multi-tenancy",title:"Multi-tenancy",description:"Introduction",source:"@site/product/use-cases/multi-tenancy.md",sourceDirName:"use-cases",slug:"/use-cases/multi-tenancy",permalink:"/product/use-cases/multi-tenancy",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/multi-tenancy.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"multi-tenancy",title:"Multi-tenancy",sidebar_label:"Multi-tenancy"},sidebar:"mainSidebar",previous:{title:"Adoption Framework",permalink:"/product/use-cases/adoption-framework"},next:{title:"CI/CD",permalink:"/product/use-cases/ci-cd"}},l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Multi-tenancy in Otomi",id:"multi-tenancy-in-otomi",level:2},{value:"Why multi-tenancy in Otomi?",id:"why-multi-tenancy-in-otomi",level:2},{value:"Prevent cluster sprawl",id:"prevent-cluster-sprawl",level:3},{value:"Fast onboarding of multiple tenants",id:"fast-onboarding-of-multiple-tenants",level:3}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,'Multi-tenant Kubernetes clusters are shared by multiple users and/or workloads which are referred to as "tenants". Operators most commonly implement resource isolation in Kubernetes, using namespaces and resource quota.'),(0,o.kt)("p",null,"The most common use cases for implementing multi-tenancy are:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/security/multi-tenancy/#multiple-teams"},"Multiple teams")," (within an organization) share a single cluster"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/security/multi-tenancy/#multiple-customers"},"Multiple customers")," share a single cluster")),(0,o.kt)("p",null,"Probably the most known tools to implement multi-tenancy are ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/clastix/capsule"},"Capsule")," and ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/loft-sh/kiosk"},"Kiosk"),". But these tools only implement multi-tenancy on cluster API level. What they don't offer is multi-tenant and role based access to shared tools on the cluster like Harbor, Vault, Git, and ArgoCD. They also don't provide isolation for container logs and custom metrics."),(0,o.kt)("p",null,"So what if you would like to offer teams or customers not only access to the Kubernetes API, but also to (automatically provisioned) access to a Git repo, a private docker registry, a space in Vault to create and manage secrets, ArgoCD, a private Prometheus instance, isolated log aggregation? This is where Otomi steps in."),(0,o.kt)("h2",{id:"multi-tenancy-in-otomi"},"Multi-tenancy in Otomi"),(0,o.kt)("p",null,"Otomi goes a step higher up in the stack. Otomi does not only provide multi-tenancy on the K8s API level, but also for shared tools on the cluster. "),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"multi-tenancy",src:n(1998).Z,width:"2025",height:"1465"})),(0,o.kt)("p",null,"When multi-tenancy in Otomi is activated (which is optional), Otomi will support the following features:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Teams are provided with a dedicated Prometheus instance for custom metrics (for metrics that should not be accessible for other tenants)"),(0,o.kt)("li",{parentName:"ol"},"Teams are provided with a dedicated Grafana instance configured with authorization, allowing only authenticated tenant members to access tenant dashboards"),(0,o.kt)("li",{parentName:"ol"},"Container logs are separated in Loki combined with authorization, allowing only authenticated tenant members access to the tenants container logs"),(0,o.kt)("li",{parentName:"ol"},"When Harbor is enabled, tenants will get access to a tenant project, allowing only authenticated tenant members to access tenant registries"),(0,o.kt)("li",{parentName:"ol"},"When Vault is enabled, tenant will get access to a space in Vault, allowing only authenticated tenant members access to tenant secrets"),(0,o.kt)("li",{parentName:"ol"},"When ArgoCD is enabled, tenants can only see the tenants ArgoCD applications created by Otomi"),(0,o.kt)("li",{parentName:"ol"},"Tenants will get access to Gitea and can create their own Git repositories"),(0,o.kt)("li",{parentName:"ol"},"Tenant namespaces are by default isolated for ingress and egress network traffic"),(0,o.kt)("li",{parentName:"ol"},"Tenants can allow other tenants to access their services"),(0,o.kt)("li",{parentName:"ol"},"Tenant services that are publicly exposed can be configured with OIDC, only allowing tenant members to access the exposed services")),(0,o.kt)("h2",{id:"why-multi-tenancy-in-otomi"},"Why multi-tenancy in Otomi?"),(0,o.kt)("h3",{id:"prevent-cluster-sprawl"},"Prevent cluster sprawl"),(0,o.kt)("p",null,"As companies look to further harness the power of cloud-native, they are adopting container technologies at rapid speed, increasing the number of clusters and workloads. As the number of Kubernetes clusters grows, this is creating increased work for Platform teams. When it comes to patching security vulnerabilities or upgrading clusters, teams are doing five times the amount of work."),(0,o.kt)("p",null,"With Otomi you can support multi-tenancy, allowing multiple tenants (like multiple development teams) to work independently on the same cluster, while sharing all the tools. Now you only have to deploy a single development cluster to support multiple development teams. This prevents you from Kubernetes cluster sprawl."),(0,o.kt)("h3",{id:"fast-onboarding-of-multiple-tenants"},"Fast onboarding of multiple tenants"),(0,o.kt)("p",null,"When a new project starts, or when a new development team would like to start using Kubernetes, onboarding usually takes a lot of time. It's not only about providing development teams access to a Kubernetes namespace. No, developers also need access to an image registry, container logs, container metrics, alerts, secrets stores, container vulnerability reports and policy compliance reports."),(0,o.kt)("p",null,"With Otomi you can onboard development teams (tenants) in just a couple of minutes, allowing them to login to the self-service portal and:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Get access to a private image registry"),(0,o.kt)("li",{parentName:"ul"},"Download the Docker login credentials to get access to their private image registry"),(0,o.kt)("li",{parentName:"ul"},"Build OCI-compliant images from application code"),(0,o.kt)("li",{parentName:"ul"},"Deploy images (stored in the private registry) using the Otomi workloads feature"),(0,o.kt)("li",{parentName:"ul"},"Get access to pre-configured dashboards to see container metrics, policy violations, detected threads in containers and detected vulnerabilities in containers"),(0,o.kt)("li",{parentName:"ul"},"Configure ingress and network policies"),(0,o.kt)("li",{parentName:"ul"},"Configure HTTP response headers"),(0,o.kt)("li",{parentName:"ul"},"Configure CNAMEs"),(0,o.kt)("li",{parentName:"ul"},"Get access to Vault to create and manage secrets"),(0,o.kt)("li",{parentName:"ul"},"Use secrets for ingress or workloads")),(0,o.kt)("p",null,"When a team already has a code repo with a Dockderfile, they can build, deploy and expose this app within minutes after they have been onboarded onto the platform."))}p.isMDXComponent=!0},1998:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/multi-tenancy-6d20d20cfd471ce025aa59ca8b3498bf.png"}}]); \ No newline at end of file diff --git a/assets/js/b4b7b186.a309c11c.js b/assets/js/b4b7b186.bce7b0b2.js similarity index 98% rename from assets/js/b4b7b186.a309c11c.js rename to assets/js/b4b7b186.bce7b0b2.js index 00e5c7468..d4b6e9d4a 100644 --- a/assets/js/b4b7b186.a309c11c.js +++ b/assets/js/b4b7b186.bce7b0b2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[3520],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>v});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),v=a,m=d["".concat(l,".").concat(v)]||d[v]||p[v]||i;return r?n.createElement(m,o(o({ref:t},u),{},{components:r})):n.createElement(m,o({ref:t},u))}));function v(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const i={slug:"serverless",title:"Serverless",sidebar_label:"Serverless"},o=void 0,s={unversionedId:"use-cases/serverless",id:"use-cases/serverless",title:"Serverless",description:"Introduction",source:"@site/product/use-cases/serverless.md",sourceDirName:"use-cases",slug:"/use-cases/serverless",permalink:"/product/use-cases/serverless",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/serverless.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"serverless",title:"Serverless",sidebar_label:"Serverless"},sidebar:"mainSidebar",previous:{title:"CI/CD",permalink:"/product/use-cases/ci-cd"},next:{title:"EULA",permalink:"/product/eula/v1"}},l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Creating Knative services",id:"creating-knative-services",level:2},{value:"Migrating Lambda functions to Knative",id:"migrating-lambda-functions-to-knative",level:2}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"introduction"},"Introduction"),(0,a.kt)("p",null,"Knative is a platform that provides tools for deploying, running, and managing ",(0,a.kt)("strong",{parentName:"p"},"serverless")," cloud-native applications to Kubernetes. Knative brings together the scalability of Kubernetes and ease of development of serverless applications, giving you more control over the resources, and allowing you to focus on the application without worrying about the infrastructure."),(0,a.kt)("p",null,"Otomi includes Knative Serving as an optional tool. Otomi installs and configures the correct version of Knative based on the used Kubernetes version and integrates Knative into the Otomi ingress architecture. All you need to do after activating Knative is to deploy a Knative service."),(0,a.kt)("h2",{id:"creating-knative-services"},"Creating Knative services"),(0,a.kt)("p",null,"There are 3 ways to deploy Knative serverless workloads in Otomi:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Create a raw Knative service manifest and add it to the teams ",(0,a.kt)("inlineCode",{parentName:"li"},"-argocd")," repository"),(0,a.kt)("li",{parentName:"ol"},"Create a Otomi serverless workload"),(0,a.kt)("li",{parentName:"ol"},"Create a Otomi workload with a custom (BYO) Helm chart")),(0,a.kt)("h2",{id:"migrating-lambda-functions-to-knative"},"Migrating Lambda functions to Knative"),(0,a.kt)("p",null,"A great way to migrate AWS Lambda functions to Kubernetes/Knative is to use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/triggermesh/knative-lambda-runtime"},"Triggermesh KLR"),". KLR (pronounced clear) are Tekton Tasks that can be used to run an AWS Lambda function in a Kubernetes cluster installed with Knative."),(0,a.kt)("p",null,"Steps:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Activate Knative and Argo CD in Otomi"),(0,a.kt)("li",{parentName:"ol"},"Create a Dockerfile, extracting the desired ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/triggermesh/knative-lambda-runtime#run-in-docker"},"runtime")),(0,a.kt)("li",{parentName:"ol"},"Build and push the image (to the private repository in Harbor)"),(0,a.kt)("li",{parentName:"ol"},"Create a Knative service using the Otomi workload feature"),(0,a.kt)("li",{parentName:"ol"},"Expose the service publicly using the Otomi services feature")))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[3520],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>v});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),v=a,m=d["".concat(l,".").concat(v)]||d[v]||p[v]||i;return r?n.createElement(m,o(o({ref:t},u),{},{components:r})):n.createElement(m,o({ref:t},u))}));function v(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const i={slug:"serverless",title:"Serverless",sidebar_label:"Serverless"},o=void 0,s={unversionedId:"use-cases/serverless",id:"use-cases/serverless",title:"Serverless",description:"Introduction",source:"@site/product/use-cases/serverless.md",sourceDirName:"use-cases",slug:"/use-cases/serverless",permalink:"/product/use-cases/serverless",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/serverless.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"serverless",title:"Serverless",sidebar_label:"Serverless"},sidebar:"mainSidebar",previous:{title:"CI/CD",permalink:"/product/use-cases/ci-cd"},next:{title:"EULA",permalink:"/product/eula/v1"}},l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Creating Knative services",id:"creating-knative-services",level:2},{value:"Migrating Lambda functions to Knative",id:"migrating-lambda-functions-to-knative",level:2}],u={toc:c};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"introduction"},"Introduction"),(0,a.kt)("p",null,"Knative is a platform that provides tools for deploying, running, and managing ",(0,a.kt)("strong",{parentName:"p"},"serverless")," cloud-native applications to Kubernetes. Knative brings together the scalability of Kubernetes and ease of development of serverless applications, giving you more control over the resources, and allowing you to focus on the application without worrying about the infrastructure."),(0,a.kt)("p",null,"Otomi includes Knative Serving as an optional tool. Otomi installs and configures the correct version of Knative based on the used Kubernetes version and integrates Knative into the Otomi ingress architecture. All you need to do after activating Knative is to deploy a Knative service."),(0,a.kt)("h2",{id:"creating-knative-services"},"Creating Knative services"),(0,a.kt)("p",null,"There are 3 ways to deploy Knative serverless workloads in Otomi:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Create a raw Knative service manifest and add it to the teams ",(0,a.kt)("inlineCode",{parentName:"li"},"-argocd")," repository"),(0,a.kt)("li",{parentName:"ol"},"Create a Otomi serverless workload"),(0,a.kt)("li",{parentName:"ol"},"Create a Otomi workload with a custom (BYO) Helm chart")),(0,a.kt)("h2",{id:"migrating-lambda-functions-to-knative"},"Migrating Lambda functions to Knative"),(0,a.kt)("p",null,"A great way to migrate AWS Lambda functions to Kubernetes/Knative is to use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/triggermesh/knative-lambda-runtime"},"Triggermesh KLR"),". KLR (pronounced clear) are Tekton Tasks that can be used to run an AWS Lambda function in a Kubernetes cluster installed with Knative."),(0,a.kt)("p",null,"Steps:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Activate Knative and Argo CD in Otomi"),(0,a.kt)("li",{parentName:"ol"},"Create a Dockerfile, extracting the desired ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/triggermesh/knative-lambda-runtime#run-in-docker"},"runtime")),(0,a.kt)("li",{parentName:"ol"},"Build and push the image (to the private repository in Harbor)"),(0,a.kt)("li",{parentName:"ol"},"Create a Knative service using the Otomi workload feature"),(0,a.kt)("li",{parentName:"ol"},"Expose the service publicly using the Otomi services feature")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c1cd9779.a3825944.js b/assets/js/c1cd9779.32fe58c3.js similarity index 99% rename from assets/js/c1cd9779.a3825944.js rename to assets/js/c1cd9779.32fe58c3.js index b719b9161..86224a18b 100644 --- a/assets/js/c1cd9779.a3825944.js +++ b/assets/js/c1cd9779.32fe58c3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[1658],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var o=n(7294);function i(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(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=i,f=d["".concat(s,".").concat(m)]||d[m]||p[m]||r;return n?o.createElement(f,a(a({ref:t},u),{},{components:n})):o.createElement(f,a({ref:t},u))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=n(7462),i=(n(7294),n(3905));const r={slug:"code-of-conduct",title:"Code of Conduct",sidebar_label:"Code of Conduct"},a=void 0,l={unversionedId:"code-of-conduct",id:"code-of-conduct",title:"Code of Conduct",description:"Our Pledge",source:"@site/community/code-of-conduct.md",sourceDirName:".",slug:"/code-of-conduct",permalink:"/community/code-of-conduct",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/code-of-conduct.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"code-of-conduct",title:"Code of Conduct",sidebar_label:"Code of Conduct"},sidebar:"mainSidebar",previous:{title:"Values",permalink:"/community/community-values"},next:{title:"Expectations",permalink:"/community/expectations"}},s={},c=[{value:"Our Pledge",id:"our-pledge",level:2},{value:"Our Standards",id:"our-standards",level:2},{value:"Enforcement Responsibilities",id:"enforcement-responsibilities",level:2},{value:"Scope",id:"scope",level:2},{value:"Enforcement",id:"enforcement",level:2},{value:"Enforcement Guidelines",id:"enforcement-guidelines",level:2},{value:"1. Correction",id:"1-correction",level:3},{value:"2. Warning",id:"2-warning",level:3},{value:"3. Temporary Ban",id:"3-temporary-ban",level:3},{value:"4. Permanent Ban",id:"4-permanent-ban",level:3},{value:"Attribution",id:"attribution",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"our-pledge"},"Our Pledge"),(0,i.kt)("p",null,"We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation."),(0,i.kt)("p",null,"We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community."),(0,i.kt)("h2",{id:"our-standards"},"Our Standards"),(0,i.kt)("p",null,"Examples of behavior that contributes to a positive environment for our community include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Demonstrating empathy and kindness toward other people"),(0,i.kt)("li",{parentName:"ul"},"Being respectful of differing opinions, viewpoints, and experiences"),(0,i.kt)("li",{parentName:"ul"},"Giving and gracefully accepting constructive feedback"),(0,i.kt)("li",{parentName:"ul"},"Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience"),(0,i.kt)("li",{parentName:"ul"},"Focusing on what is best not just for us as individuals, but for the overall community")),(0,i.kt)("p",null,"Examples of unacceptable behavior include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The use of sexualized language or imagery, and sexual attention or advances of any kind"),(0,i.kt)("li",{parentName:"ul"},"Trolling, insulting or derogatory comments, and personal or political attacks"),(0,i.kt)("li",{parentName:"ul"},"Public or private harassment"),(0,i.kt)("li",{parentName:"ul"},"Publishing others' private information, such as a physical or email address, without their explicit permission"),(0,i.kt)("li",{parentName:"ul"},"Other conduct which could reasonably be considered inappropriate in a professional setting")),(0,i.kt)("h2",{id:"enforcement-responsibilities"},"Enforcement Responsibilities"),(0,i.kt)("p",null,"Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful."),(0,i.kt)("p",null,"Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate."),(0,i.kt)("h2",{id:"scope"},"Scope"),(0,i.kt)("p",null,"This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event."),(0,i.kt)("h2",{id:"enforcement"},"Enforcement"),(0,i.kt)("p",null,"Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at ",(0,i.kt)("a",{parentName:"p",href:"mailto:community@redkubes.com."},"community@redkubes.com.")," All complaints will be reviewed and investigated promptly and fairly."),(0,i.kt)("p",null,"All community leaders are obligated to respect the privacy and security of the reporter of any incident."),(0,i.kt)("h2",{id:"enforcement-guidelines"},"Enforcement Guidelines"),(0,i.kt)("p",null,"Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:"),(0,i.kt)("h3",{id:"1-correction"},"1. Correction"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested."),(0,i.kt)("h3",{id:"2-warning"},"2. Warning"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A violation through a single incident or series of actions."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban."),(0,i.kt)("h3",{id:"3-temporary-ban"},"3. Temporary Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A serious violation of community standards, including sustained inappropriate behavior."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban."),(0,i.kt)("h3",{id:"4-permanent-ban"},"4. Permanent Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A permanent ban from any sort of public interaction within the community."),(0,i.kt)("h2",{id:"attribution"},"Attribution"),(0,i.kt)("p",null,"This Code of Conduct is adapted from the ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org"},"Contributor Covenant"),", version 2.0, available at ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/version/2/0/code_of_conduct.html"},"v2.0"),"."),(0,i.kt)("p",null,"Community Impact Guidelines were inspired by ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mozilla/diversity"},"Mozilla's code of conduct enforcement ladder"),"."),(0,i.kt)("p",null,"For answers to common questions about this code of conduct, see the FAQ at ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/faq"},"https://www.contributor-covenant.org/faq"),". Translations are available at ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/translations"},"https://www.contributor-covenant.org/translations"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[1658],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var o=n(7294);function i(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(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(n),m=i,f=d["".concat(s,".").concat(m)]||d[m]||p[m]||r;return n?o.createElement(f,a(a({ref:t},u),{},{components:n})):o.createElement(f,a({ref:t},u))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=n(7462),i=(n(7294),n(3905));const r={slug:"code-of-conduct",title:"Code of Conduct",sidebar_label:"Code of Conduct"},a=void 0,l={unversionedId:"code-of-conduct",id:"code-of-conduct",title:"Code of Conduct",description:"Our Pledge",source:"@site/community/code-of-conduct.md",sourceDirName:".",slug:"/code-of-conduct",permalink:"/community/code-of-conduct",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/code-of-conduct.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"code-of-conduct",title:"Code of Conduct",sidebar_label:"Code of Conduct"},sidebar:"mainSidebar",previous:{title:"Values",permalink:"/community/community-values"},next:{title:"Expectations",permalink:"/community/expectations"}},s={},c=[{value:"Our Pledge",id:"our-pledge",level:2},{value:"Our Standards",id:"our-standards",level:2},{value:"Enforcement Responsibilities",id:"enforcement-responsibilities",level:2},{value:"Scope",id:"scope",level:2},{value:"Enforcement",id:"enforcement",level:2},{value:"Enforcement Guidelines",id:"enforcement-guidelines",level:2},{value:"1. Correction",id:"1-correction",level:3},{value:"2. Warning",id:"2-warning",level:3},{value:"3. Temporary Ban",id:"3-temporary-ban",level:3},{value:"4. Permanent Ban",id:"4-permanent-ban",level:3},{value:"Attribution",id:"attribution",level:2}],u={toc:c};function p(e){let{components:t,...n}=e;return(0,i.kt)("wrapper",(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"our-pledge"},"Our Pledge"),(0,i.kt)("p",null,"We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation."),(0,i.kt)("p",null,"We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community."),(0,i.kt)("h2",{id:"our-standards"},"Our Standards"),(0,i.kt)("p",null,"Examples of behavior that contributes to a positive environment for our community include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Demonstrating empathy and kindness toward other people"),(0,i.kt)("li",{parentName:"ul"},"Being respectful of differing opinions, viewpoints, and experiences"),(0,i.kt)("li",{parentName:"ul"},"Giving and gracefully accepting constructive feedback"),(0,i.kt)("li",{parentName:"ul"},"Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience"),(0,i.kt)("li",{parentName:"ul"},"Focusing on what is best not just for us as individuals, but for the overall community")),(0,i.kt)("p",null,"Examples of unacceptable behavior include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The use of sexualized language or imagery, and sexual attention or advances of any kind"),(0,i.kt)("li",{parentName:"ul"},"Trolling, insulting or derogatory comments, and personal or political attacks"),(0,i.kt)("li",{parentName:"ul"},"Public or private harassment"),(0,i.kt)("li",{parentName:"ul"},"Publishing others' private information, such as a physical or email address, without their explicit permission"),(0,i.kt)("li",{parentName:"ul"},"Other conduct which could reasonably be considered inappropriate in a professional setting")),(0,i.kt)("h2",{id:"enforcement-responsibilities"},"Enforcement Responsibilities"),(0,i.kt)("p",null,"Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful."),(0,i.kt)("p",null,"Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate."),(0,i.kt)("h2",{id:"scope"},"Scope"),(0,i.kt)("p",null,"This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event."),(0,i.kt)("h2",{id:"enforcement"},"Enforcement"),(0,i.kt)("p",null,"Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at ",(0,i.kt)("a",{parentName:"p",href:"mailto:community@redkubes.com."},"community@redkubes.com.")," All complaints will be reviewed and investigated promptly and fairly."),(0,i.kt)("p",null,"All community leaders are obligated to respect the privacy and security of the reporter of any incident."),(0,i.kt)("h2",{id:"enforcement-guidelines"},"Enforcement Guidelines"),(0,i.kt)("p",null,"Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:"),(0,i.kt)("h3",{id:"1-correction"},"1. Correction"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested."),(0,i.kt)("h3",{id:"2-warning"},"2. Warning"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A violation through a single incident or series of actions."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban."),(0,i.kt)("h3",{id:"3-temporary-ban"},"3. Temporary Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": A serious violation of community standards, including sustained inappropriate behavior."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban."),(0,i.kt)("h3",{id:"4-permanent-ban"},"4. Permanent Ban"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Community Impact"),": Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals."),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Consequence"),": A permanent ban from any sort of public interaction within the community."),(0,i.kt)("h2",{id:"attribution"},"Attribution"),(0,i.kt)("p",null,"This Code of Conduct is adapted from the ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org"},"Contributor Covenant"),", version 2.0, available at ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/version/2/0/code_of_conduct.html"},"v2.0"),"."),(0,i.kt)("p",null,"Community Impact Guidelines were inspired by ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mozilla/diversity"},"Mozilla's code of conduct enforcement ladder"),"."),(0,i.kt)("p",null,"For answers to common questions about this code of conduct, see the FAQ at ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/faq"},"https://www.contributor-covenant.org/faq"),". Translations are available at ",(0,i.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/translations"},"https://www.contributor-covenant.org/translations"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c642c7e8.615682bb.js b/assets/js/c642c7e8.ebf89696.js similarity index 98% rename from assets/js/c642c7e8.615682bb.js rename to assets/js/c642c7e8.ebf89696.js index abef04777..878999fa2 100644 --- a/assets/js/c642c7e8.615682bb.js +++ b/assets/js/c642c7e8.ebf89696.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[512],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>p});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var u=n.createContext({}),s=function(e){var t=n.useContext(u),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},c=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=s(o),p=r,f=m["".concat(u,".").concat(p)]||m[p]||d[p]||i;return o?n.createElement(f,a(a({ref:t},c),{},{components:o})):n.createElement(f,a({ref:t},c))}));function p(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=o(7462),r=(o(7294),o(3905));const i={title:"Welcome to our community",slug:"welcome",sidebar_label:"Welcome"},a=void 0,l={unversionedId:"welcome",id:"welcome",title:"Welcome to our community",description:"So you are interested to get involved with Otomi? Awesome! This guide will help you understand the overall organization of the project, and direct you to the best places to get started. You'll be able to pick up issues, write code to fix them, and get your work reviewed and merged. All feedback is welcome!",source:"@site/community/welcome.md",sourceDirName:".",slug:"/welcome",permalink:"/community/welcome",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/welcome.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{title:"Welcome to our community",slug:"welcome",sidebar_label:"Welcome"},sidebar:"mainSidebar",next:{title:"Values",permalink:"/community/community-values"}},u={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Code of Conduct",id:"code-of-conduct",level:3},{value:"Developer guide",id:"developer-guide",level:3},{value:"Setting up your development environment",id:"setting-up-your-development-environment",level:3},{value:"Community Expectations and Roles",id:"community-expectations-and-roles",level:3}],c={toc:s};function d(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"So you are interested to get involved with Otomi? Awesome! This guide will help you understand the overall organization of the project, and direct you to the best places to get started. You'll be able to pick up issues, write code to fix them, and get your work reviewed and merged. All feedback is welcome!"),(0,r.kt)("p",null,"This document is the single source of truth for how to contribute to the following code bases:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/redkubes/otomi-core/"},"otomi-core"),": The heart of Otomi, a monorepo containing all the apps and configurations"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/redkubes/otomi-tasks/"},"otomi-tasks"),": The tasks used by core to massage apps to adhere to the configurations"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/redkubes/otomi-clients/"},"otomi-clients"),": The openapi generator for the clients used by the tasks")),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Before submitting code to Otomi, you should first complete the following prerequisites. Completing these steps will make your first contribution easier:"),(0,r.kt)("h3",{id:"code-of-conduct"},"Code of Conduct"),(0,r.kt)("p",null,"Please make sure to read and observe the ",(0,r.kt)("a",{parentName:"p",href:"code-of-conduct"},"Code of Conduct")," and\n",(0,r.kt)("a",{parentName:"p",href:"community-values"},"Community Values")),(0,r.kt)("h3",{id:"developer-guide"},"Developer guide"),(0,r.kt)("p",null,"Effective development starts with an understanding the code structure and the relationship between different components of the system. Read the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/redkubes/otomi-core/blob/main/docs/development.md"},"Code development guide")," to learn how to develop on Otomi."),(0,r.kt)("h3",{id:"setting-up-your-development-environment"},"Setting up your development environment"),(0,r.kt)("p",null,"It is not required to set up a developer environment in order to contribute to Otomi, but if you do plan to contribute code changes, follow the instructions in the Developer Docs on how to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/redkubes/otomi-core/blob/main/docs/setup.md"},"Set up your development environment"),"."),(0,r.kt)("h3",{id:"community-expectations-and-roles"},"Community Expectations and Roles"),(0,r.kt)("p",null,"Otomi is a community project. Consequently, it is wholly dependent on its community to provide a productive, friendly and collaborative environment."),(0,r.kt)("p",null,"Please read and review the ",(0,r.kt)("a",{parentName:"p",href:"expectations"},"Contribution Expectations")," for an understanding of code and review expectations."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[512],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>p});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var u=n.createContext({}),s=function(e){var t=n.useContext(u),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},c=function(e){var t=s(e.components);return n.createElement(u.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=s(o),p=r,f=m["".concat(u,".").concat(p)]||m[p]||d[p]||i;return o?n.createElement(f,a(a({ref:t},c),{},{components:o})):n.createElement(f,a({ref:t},c))}));function p(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=m;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:r,a[1]=l;for(var s=2;s{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=o(7462),r=(o(7294),o(3905));const i={title:"Welcome to our community",slug:"welcome",sidebar_label:"Welcome"},a=void 0,l={unversionedId:"welcome",id:"welcome",title:"Welcome to our community",description:"So you are interested to get involved with Otomi? Awesome! This guide will help you understand the overall organization of the project, and direct you to the best places to get started. You'll be able to pick up issues, write code to fix them, and get your work reviewed and merged. All feedback is welcome!",source:"@site/community/welcome.md",sourceDirName:".",slug:"/welcome",permalink:"/community/welcome",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/welcome.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{title:"Welcome to our community",slug:"welcome",sidebar_label:"Welcome"},sidebar:"mainSidebar",next:{title:"Values",permalink:"/community/community-values"}},u={},s=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Code of Conduct",id:"code-of-conduct",level:3},{value:"Developer guide",id:"developer-guide",level:3},{value:"Setting up your development environment",id:"setting-up-your-development-environment",level:3},{value:"Community Expectations and Roles",id:"community-expectations-and-roles",level:3}],c={toc:s};function d(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"So you are interested to get involved with Otomi? Awesome! This guide will help you understand the overall organization of the project, and direct you to the best places to get started. You'll be able to pick up issues, write code to fix them, and get your work reviewed and merged. All feedback is welcome!"),(0,r.kt)("p",null,"This document is the single source of truth for how to contribute to the following code bases:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/redkubes/otomi-core/"},"otomi-core"),": The heart of Otomi, a monorepo containing all the apps and configurations"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/redkubes/otomi-tasks/"},"otomi-tasks"),": The tasks used by core to massage apps to adhere to the configurations"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/redkubes/otomi-clients/"},"otomi-clients"),": The openapi generator for the clients used by the tasks")),(0,r.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,r.kt)("p",null,"Before submitting code to Otomi, you should first complete the following prerequisites. Completing these steps will make your first contribution easier:"),(0,r.kt)("h3",{id:"code-of-conduct"},"Code of Conduct"),(0,r.kt)("p",null,"Please make sure to read and observe the ",(0,r.kt)("a",{parentName:"p",href:"code-of-conduct"},"Code of Conduct")," and\n",(0,r.kt)("a",{parentName:"p",href:"community-values"},"Community Values")),(0,r.kt)("h3",{id:"developer-guide"},"Developer guide"),(0,r.kt)("p",null,"Effective development starts with an understanding the code structure and the relationship between different components of the system. Read the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/redkubes/otomi-core/blob/main/docs/development.md"},"Code development guide")," to learn how to develop on Otomi."),(0,r.kt)("h3",{id:"setting-up-your-development-environment"},"Setting up your development environment"),(0,r.kt)("p",null,"It is not required to set up a developer environment in order to contribute to Otomi, but if you do plan to contribute code changes, follow the instructions in the Developer Docs on how to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/redkubes/otomi-core/blob/main/docs/setup.md"},"Set up your development environment"),"."),(0,r.kt)("h3",{id:"community-expectations-and-roles"},"Community Expectations and Roles"),(0,r.kt)("p",null,"Otomi is a community project. Consequently, it is wholly dependent on its community to provide a productive, friendly and collaborative environment."),(0,r.kt)("p",null,"Please read and review the ",(0,r.kt)("a",{parentName:"p",href:"expectations"},"Contribution Expectations")," for an understanding of code and review expectations."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d673e682.a29acf9e.js b/assets/js/d673e682.1f14e98a.js similarity index 98% rename from assets/js/d673e682.a29acf9e.js rename to assets/js/d673e682.1f14e98a.js index 51ac1e094..f4cb551a7 100644 --- a/assets/js/d673e682.a29acf9e.js +++ b/assets/js/d673e682.1f14e98a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[3120],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>m});var r=o(7294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function n(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var o=e.components,i=e.mdxType,n=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(o),m=i,h=p["".concat(c,".").concat(m)]||p[m]||d[m]||n;return o?r.createElement(h,a(a({ref:t},u),{},{components:o})):r.createElement(h,a({ref:t},u))}));function m(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var n=o.length,a=new Array(n);a[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>n,metadata:()=>s,toc:()=>l});var r=o(7462),i=(o(7294),o(3905));const n={slug:"ci-cd",title:"CI/CD",sidebar_label:"CI/CD"},a=void 0,s={unversionedId:"use-cases/ci-cd",id:"use-cases/ci-cd",title:"CI/CD",description:"Introduction",source:"@site/product/use-cases/ci-cd.md",sourceDirName:"use-cases",slug:"/use-cases/ci-cd",permalink:"/product/use-cases/ci-cd",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/ci-cd.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"ci-cd",title:"CI/CD",sidebar_label:"CI/CD"},sidebar:"mainSidebar",previous:{title:"Multi-tenancy",permalink:"/product/use-cases/multi-tenancy"},next:{title:"Serverless",permalink:"/product/use-cases/serverless"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"CI with Otomi",id:"ci-with-otomi",level:2},{value:"CD with Otomi",id:"cd-with-otomi",level:2}],u={toc:l};function d(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,r.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,"Otomi adds developer- and operations-centric tools, automation and self-service on top of Kubernetes. The integrated tools mainly focus on Continuous Deployment (to automatically deploy code changes after the build stage) and on all runtime controls. When using Otomi, we advice to setup a seprate CI environment (using specialized CI tools like GitHub Actions or CircleCI) where artifacts (images) are build and then pushed to an image registry (like Harbor provided by Otomi). But with integrated tools like Gitea and Drone, Otomi can in some cases also be used for Continuous Integration (CI). This can be especially interesting in greenfield environments (where there is (not yet) a full CI toolset implemented) or in isolated environments (where developers don't have access to cloud CI services)."),(0,i.kt)("h2",{id:"ci-with-otomi"},"CI with Otomi"),(0,i.kt)("p",null,"Users on the platform can get access to an organization in Gitea. See ",(0,i.kt)("a",{parentName:"p",href:"https://docs.gitea.io/en-us/comparison/"},"here")," for a full list of all Gitea features and a comparison with other self-hosted Git solutions. By adding a Drone pipeline to a Git repository, users can take advantage of Drone to automate steps in the software delivery process, such as initiating code builds, running automated tests, and pushing images to a private image registry in harbor."),(0,i.kt)("p",null,"Next to using Drone for build pipelines, Otomi also includes Tekton pipelines. Tekton is used for the build feature in Otomi. The build feature can be used to build images from source using Kaniko (when there is a Docker file), or Buildpacks. To use the build feature, source code needs to be in a private Gitea repo, or in a public git repo. Other private repo's can also be replicated to Gitea."),(0,i.kt)("h2",{id:"cd-with-otomi"},"CD with Otomi"),(0,i.kt)("p",null,"The most common workflow when using Otomi starts when an artifact (image) has been build. Using the workloads feature in Otomi, images can be used in 3 supported types of workloads:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"A Kubernetes ",(0,i.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment"),", combined with an ","[HPA]","(",(0,i.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/"},"https://kubernetes.io/docs/tasks/")),(0,i.kt)("li",{parentName:"ol"},"(if Knative is enabled) A ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/knative/specs/blob/main/specs/serving/knative-api-specification-1.0.md#service"},"Knative service")),(0,i.kt)("li",{parentName:"ol"},"A custom (BYO) Helm chart")),(0,i.kt)("p",null,"Otomi uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"otomi-charts")," repository that contains a library of curated Helm charts that are used to deploy the supported workload types. When a workload specification (a combination of a Helm chart with custom values) has been created, Otomi automatically creates an Argo CD applicationset that deploys the configured chart. A workload can also be configured with the ",(0,i.kt)("a",{parentName:"p",href:"https://argocd-image-updater.readthedocs.io/en/stable/"},"Argo CD Image Updater")," that can check for new versions of the container images that are deployed with the workload and automatically update the workload to the latest allowed version. The Argo CD Image Updater is only supported in combination with Otomi workloads and images stored in Harbor."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[3120],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>m});var r=o(7294);function i(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function n(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function a(e){for(var t=1;t=0||(i[o]=e[o]);return i}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(i[o]=e[o])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var o=e.components,i=e.mdxType,n=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(o),m=i,h=p["".concat(c,".").concat(m)]||p[m]||d[m]||n;return o?r.createElement(h,a(a({ref:t},u),{},{components:o})):r.createElement(h,a({ref:t},u))}));function m(e,t){var o=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var n=o.length,a=new Array(n);a[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:i,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>n,metadata:()=>s,toc:()=>l});var r=o(7462),i=(o(7294),o(3905));const n={slug:"ci-cd",title:"CI/CD",sidebar_label:"CI/CD"},a=void 0,s={unversionedId:"use-cases/ci-cd",id:"use-cases/ci-cd",title:"CI/CD",description:"Introduction",source:"@site/product/use-cases/ci-cd.md",sourceDirName:"use-cases",slug:"/use-cases/ci-cd",permalink:"/product/use-cases/ci-cd",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/use-cases/ci-cd.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"ci-cd",title:"CI/CD",sidebar_label:"CI/CD"},sidebar:"mainSidebar",previous:{title:"Multi-tenancy",permalink:"/product/use-cases/multi-tenancy"},next:{title:"Serverless",permalink:"/product/use-cases/serverless"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"CI with Otomi",id:"ci-with-otomi",level:2},{value:"CD with Otomi",id:"cd-with-otomi",level:2}],u={toc:l};function d(e){let{components:t,...o}=e;return(0,i.kt)("wrapper",(0,r.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,"Otomi adds developer- and operations-centric tools, automation and self-service on top of Kubernetes. The integrated tools mainly focus on Continuous Deployment (to automatically deploy code changes after the build stage) and on all runtime controls. When using Otomi, we advice to setup a seprate CI environment (using specialized CI tools like GitHub Actions or CircleCI) where artifacts (images) are build and then pushed to an image registry (like Harbor provided by Otomi). But with integrated tools like Gitea and Drone, Otomi can in some cases also be used for Continuous Integration (CI). This can be especially interesting in greenfield environments (where there is (not yet) a full CI toolset implemented) or in isolated environments (where developers don't have access to cloud CI services)."),(0,i.kt)("h2",{id:"ci-with-otomi"},"CI with Otomi"),(0,i.kt)("p",null,"Users on the platform can get access to an organization in Gitea. See ",(0,i.kt)("a",{parentName:"p",href:"https://docs.gitea.io/en-us/comparison/"},"here")," for a full list of all Gitea features and a comparison with other self-hosted Git solutions. By adding a Drone pipeline to a Git repository, users can take advantage of Drone to automate steps in the software delivery process, such as initiating code builds, running automated tests, and pushing images to a private image registry in harbor."),(0,i.kt)("p",null,"Next to using Drone for build pipelines, Otomi also includes Tekton pipelines. Tekton is used for the build feature in Otomi. The build feature can be used to build images from source using Kaniko (when there is a Docker file), or Buildpacks. To use the build feature, source code needs to be in a private Gitea repo, or in a public git repo. Other private repo's can also be replicated to Gitea."),(0,i.kt)("h2",{id:"cd-with-otomi"},"CD with Otomi"),(0,i.kt)("p",null,"The most common workflow when using Otomi starts when an artifact (image) has been build. Using the workloads feature in Otomi, images can be used in 3 supported types of workloads:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"A Kubernetes ",(0,i.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"},"Deployment"),", combined with an ","[HPA]","(",(0,i.kt)("a",{parentName:"li",href:"https://kubernetes.io/docs/tasks/"},"https://kubernetes.io/docs/tasks/")),(0,i.kt)("li",{parentName:"ol"},"(if Knative is enabled) A ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/knative/specs/blob/main/specs/serving/knative-api-specification-1.0.md#service"},"Knative service")),(0,i.kt)("li",{parentName:"ol"},"A custom (BYO) Helm chart")),(0,i.kt)("p",null,"Otomi uses the ",(0,i.kt)("inlineCode",{parentName:"p"},"otomi-charts")," repository that contains a library of curated Helm charts that are used to deploy the supported workload types. When a workload specification (a combination of a Helm chart with custom values) has been created, Otomi automatically creates an Argo CD applicationset that deploys the configured chart. A workload can also be configured with the ",(0,i.kt)("a",{parentName:"p",href:"https://argocd-image-updater.readthedocs.io/en/stable/"},"Argo CD Image Updater")," that can check for new versions of the container images that are deployed with the workload and automatically update the workload to the latest allowed version. The Argo CD Image Updater is only supported in combination with Otomi workloads and images stored in Harbor."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e878c199.1d4e6f4b.js b/assets/js/e878c199.e3839f95.js similarity index 98% rename from assets/js/e878c199.1d4e6f4b.js rename to assets/js/e878c199.e3839f95.js index a6f47d6c5..e624fcb63 100644 --- a/assets/js/e878c199.1d4e6f4b.js +++ b/assets/js/e878c199.e3839f95.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2163],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>d});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var u=n.createContext({}),l=function(e){var t=n.useContext(u),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},c=function(e){var t=l(e.components);return n.createElement(u.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=l(o),d=r,h=p["".concat(u,".").concat(d)]||p[d]||m[d]||i;return o?n.createElement(h,a(a({ref:t},c),{},{components:o})):n.createElement(h,a({ref:t},c))}));function d(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=p;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=o(7462),r=(o(7294),o(3905));const i={title:"Otomi Community Values",slug:"community-values",sidebar_label:"Values"},a="Otomi Community Values",s={unversionedId:"values",id:"values",title:"Otomi Community Values",description:'Otomi Community culture contributes substantially to the project\'s success. The following values (blatantly copied and adopted from kubernetes, as those are almost "universal") are central to this:',source:"@site/community/values.md",sourceDirName:".",slug:"/community-values",permalink:"/community/community-values",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/values.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{title:"Otomi Community Values",slug:"community-values",sidebar_label:"Values"},sidebar:"mainSidebar",previous:{title:"Welcome",permalink:"/community/welcome"},next:{title:"Code of Conduct",permalink:"/community/code-of-conduct"}},u={},l=[{value:"Distribution is better than centralization",id:"distribution-is-better-than-centralization",level:2},{value:"Community over product or company",id:"community-over-product-or-company",level:2},{value:"Automation over process",id:"automation-over-process",level:2},{value:"Inclusive is better than exclusive",id:"inclusive-is-better-than-exclusive",level:2},{value:"Evolution is better than stagnation",id:"evolution-is-better-than-stagnation",level:2}],c={toc:l};function m(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"otomi-community-values"},"Otomi Community Values"),(0,r.kt)("p",null,'Otomi Community culture contributes substantially to the project\'s success. The following values (blatantly copied and adopted from kubernetes, as those are almost "universal") are central to this:'),(0,r.kt)("h2",{id:"distribution-is-better-than-centralization"},"Distribution is better than centralization"),(0,r.kt)("p",null,"The scale of the Otomi project is only viable through high-trust and high-visibility distribution of work, which includes delegation of authority, decision making, technical design, code ownership, and documentation. Distributed asynchronous ownership, collaboration, communication and decision making are the cornerstones of our community."),(0,r.kt)("h2",{id:"community-over-product-or-company"},"Community over product or company"),(0,r.kt)("p",null,"We are here as a community first. Our allegiance is to the intentional stewardship of the Otomi project for the benefit of all its members and users everywhere. We support working together publicly for the common goal of a vibrant interoperable ecosystem, providing an excellent experience for our users. Individuals gain status through work. Companies gain status through their commitments to support this community and fund the resources necessary for the project to operate."),(0,r.kt)("h2",{id:"automation-over-process"},"Automation over process"),(0,r.kt)("p",null,"Large projects have a lot of hard yet less exciting work. We value time spent automating repetitive work more highly than toil. Where work cannot be automated, our culture recognizes and rewards all types of contributions while recognizing that heroism is not sustainable."),(0,r.kt)("h2",{id:"inclusive-is-better-than-exclusive"},"Inclusive is better than exclusive"),(0,r.kt)("p",null,"Broadly successful and useful technologies require different perspectives and skill sets, which can only be heard in a welcoming and respectful environment. Community membership is a privilege, not a right. Community members earn leadership through effort, scope, quality, quantity, and duration of contributions. Our community respects the time and effort put into a discussion, regardless of where a contributor is on their growth path."),(0,r.kt)("h2",{id:"evolution-is-better-than-stagnation"},"Evolution is better than stagnation"),(0,r.kt)("p",null,"Openness to new ideas and studied technological evolution make Otomi a stronger project. Continual improvement, servant leadership, mentorship, and respect are the foundations of Otomi culture. Otomi community leaders have a duty to find, sponsor, and promote new community members. Leaders should expect to step aside. Community members should expect to step up."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},'"Culture eats strategy for breakfast." --Peter Drucker')))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[2163],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>d});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var u=n.createContext({}),l=function(e){var t=n.useContext(u),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},c=function(e){var t=l(e.components);return n.createElement(u.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=l(o),d=r,h=p["".concat(u,".").concat(d)]||p[d]||m[d]||i;return o?n.createElement(h,a(a({ref:t},c),{},{components:o})):n.createElement(h,a({ref:t},c))}));function d(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=p;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s.mdxType="string"==typeof e?e:r,a[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=o(7462),r=(o(7294),o(3905));const i={title:"Otomi Community Values",slug:"community-values",sidebar_label:"Values"},a="Otomi Community Values",s={unversionedId:"values",id:"values",title:"Otomi Community Values",description:'Otomi Community culture contributes substantially to the project\'s success. The following values (blatantly copied and adopted from kubernetes, as those are almost "universal") are central to this:',source:"@site/community/values.md",sourceDirName:".",slug:"/community-values",permalink:"/community/community-values",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/community/values.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{title:"Otomi Community Values",slug:"community-values",sidebar_label:"Values"},sidebar:"mainSidebar",previous:{title:"Welcome",permalink:"/community/welcome"},next:{title:"Code of Conduct",permalink:"/community/code-of-conduct"}},u={},l=[{value:"Distribution is better than centralization",id:"distribution-is-better-than-centralization",level:2},{value:"Community over product or company",id:"community-over-product-or-company",level:2},{value:"Automation over process",id:"automation-over-process",level:2},{value:"Inclusive is better than exclusive",id:"inclusive-is-better-than-exclusive",level:2},{value:"Evolution is better than stagnation",id:"evolution-is-better-than-stagnation",level:2}],c={toc:l};function m(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"otomi-community-values"},"Otomi Community Values"),(0,r.kt)("p",null,'Otomi Community culture contributes substantially to the project\'s success. The following values (blatantly copied and adopted from kubernetes, as those are almost "universal") are central to this:'),(0,r.kt)("h2",{id:"distribution-is-better-than-centralization"},"Distribution is better than centralization"),(0,r.kt)("p",null,"The scale of the Otomi project is only viable through high-trust and high-visibility distribution of work, which includes delegation of authority, decision making, technical design, code ownership, and documentation. Distributed asynchronous ownership, collaboration, communication and decision making are the cornerstones of our community."),(0,r.kt)("h2",{id:"community-over-product-or-company"},"Community over product or company"),(0,r.kt)("p",null,"We are here as a community first. Our allegiance is to the intentional stewardship of the Otomi project for the benefit of all its members and users everywhere. We support working together publicly for the common goal of a vibrant interoperable ecosystem, providing an excellent experience for our users. Individuals gain status through work. Companies gain status through their commitments to support this community and fund the resources necessary for the project to operate."),(0,r.kt)("h2",{id:"automation-over-process"},"Automation over process"),(0,r.kt)("p",null,"Large projects have a lot of hard yet less exciting work. We value time spent automating repetitive work more highly than toil. Where work cannot be automated, our culture recognizes and rewards all types of contributions while recognizing that heroism is not sustainable."),(0,r.kt)("h2",{id:"inclusive-is-better-than-exclusive"},"Inclusive is better than exclusive"),(0,r.kt)("p",null,"Broadly successful and useful technologies require different perspectives and skill sets, which can only be heard in a welcoming and respectful environment. Community membership is a privilege, not a right. Community members earn leadership through effort, scope, quality, quantity, and duration of contributions. Our community respects the time and effort put into a discussion, regardless of where a contributor is on their growth path."),(0,r.kt)("h2",{id:"evolution-is-better-than-stagnation"},"Evolution is better than stagnation"),(0,r.kt)("p",null,"Openness to new ideas and studied technological evolution make Otomi a stronger project. Continual improvement, servant leadership, mentorship, and respect are the foundations of Otomi culture. Otomi community leaders have a duty to find, sponsor, and promote new community members. Leaders should expect to step aside. Community members should expect to step up."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},'"Culture eats strategy for breakfast." --Peter Drucker')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/efb16635.388f9ffb.js b/assets/js/efb16635.271b179f.js similarity index 55% rename from assets/js/efb16635.388f9ffb.js rename to assets/js/efb16635.271b179f.js index a367bdbad..c1d9450fb 100644 --- a/assets/js/efb16635.388f9ffb.js +++ b/assets/js/efb16635.271b179f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[8773],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var a=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=n(e,["components","mdxType","originalType","parentName"]),c=p(r),d=i,f=c["".concat(s,".").concat(d)]||c[d]||m[d]||o;return r?a.createElement(f,l(l({ref:t},u),{},{components:r})):a.createElement(f,l({ref:t},u))}));function d(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,l=new Array(o);l[0]=c;var n={};for(var s in t)hasOwnProperty.call(t,s)&&(n[s]=t[s]);n.originalType=e,n.mdxType="string"==typeof e?e:i,l[1]=n;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>n,toc:()=>p});var a=r(7462),i=(r(7294),r(3905));const o={slug:"overview",title:"Get started with Otomi for Developers",sidebar_label:"Get Started Labs"},l=void 0,n={unversionedId:"for-devs/get-started/overview",id:"for-devs/get-started/overview",title:"Get started with Otomi for Developers",description:"Welcome to Otomi! If you are a developer and are going to use Otomi Platform, these getting started labs are for you. Step by step we'll guide you in using Otomi to deploy and manage your containerized applications. The getting started with Otomi for developers contains a set of labs to cover the most common developer activities.",source:"@site/docs/for-devs/get-started/overview.md",sourceDirName:"for-devs/get-started",slug:"/for-devs/get-started/overview",permalink:"/docs/for-devs/get-started/overview",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/tree/main/docs/for-devs/get-started/overview.md",tags:[],version:"current",frontMatter:{slug:"overview",title:"Get started with Otomi for Developers",sidebar_label:"Get Started Labs"},sidebar:"mainSidebar",previous:{title:"Activation",permalink:"/docs/get-started/activation"},next:{title:"Overview",permalink:"/docs/for-ops/console/overview"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Building images",id:"building-images",level:2},{value:"Deploy application workloads",id:"deploy-application-workloads",level:2},{value:"Secure",id:"secure",level:2},{value:"Expose",id:"expose",level:2},{value:"Monitor",id:"monitor",level:2}],u={toc:p};function m(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Welcome to Otomi! If you are a developer and are going to use Otomi Platform, these getting started labs are for you. Step by step we'll guide you in using Otomi to deploy and manage your containerized applications. The getting started with Otomi for developers contains a set of labs to cover the most common developer activities."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-1"},"Prerequisites")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-2"},"Access Otomi Console"))),(0,i.kt)("h2",{id:"building-images"},"Building images"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-3"},"Create a private Git repo")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-4"},"Create a CI (build) pipeline")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-5"},"Push container images to your private repo")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-6"},"Create builds using Otomi")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-7"},"Scan your images for vulnerabilities"))),(0,i.kt)("h2",{id:"deploy-application-workloads"},"Deploy application workloads"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-8"},"Create secrets")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-10"},"BYO manifest to deploy a workload with ArgoCD")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-11"},"Configure ArgoCD image updater")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-12"},"Create workloads using BYO Helm charts")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-13"},"Create workloads using Otomi charts")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-24"},"Create a PostgreSQL database"))),(0,i.kt)("h2",{id:"secure"},"Secure"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-15"},"Check policy compliance")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-17"},"Scan your running containers for vulnerabilities"))),(0,i.kt)("h2",{id:"expose"},"Expose"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-18"},"Publicly expose a service")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-19"},"Configuring network policies"))),(0,i.kt)("h2",{id:"monitor"},"Monitor"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-20"},"View container logs")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-21"},"View container metrics")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-22"},"Monitor custom metrics")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-23"},"Monitoring service availability")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-25"},"Monitor databases"))))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[8773],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var a=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=a.createContext({}),p=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var r=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,u=n(e,["components","mdxType","originalType","parentName"]),c=p(r),d=i,f=c["".concat(s,".").concat(d)]||c[d]||m[d]||l;return r?a.createElement(f,o(o({ref:t},u),{},{components:r})):a.createElement(f,o({ref:t},u))}));function d(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var l=r.length,o=new Array(l);o[0]=c;var n={};for(var s in t)hasOwnProperty.call(t,s)&&(n[s]=t[s]);n.originalType=e,n.mdxType="string"==typeof e?e:i,o[1]=n;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>n,toc:()=>p});var a=r(7462),i=(r(7294),r(3905));const l={slug:"overview",title:"Get started with Otomi for Developers",sidebar_label:"Get Started Labs"},o=void 0,n={unversionedId:"for-devs/get-started/overview",id:"for-devs/get-started/overview",title:"Get started with Otomi for Developers",description:"Welcome to Otomi! If you are a developer and are going to use Otomi Platform, these getting started labs are for you. Step by step we'll guide you in using Otomi to deploy and manage your containerized applications. The getting started with Otomi for developers contains a set of labs to cover the most common developer activities.",source:"@site/docs/for-devs/get-started/overview.md",sourceDirName:"for-devs/get-started",slug:"/for-devs/get-started/overview",permalink:"/docs/for-devs/get-started/overview",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/tree/main/docs/for-devs/get-started/overview.md",tags:[],version:"current",frontMatter:{slug:"overview",title:"Get started with Otomi for Developers",sidebar_label:"Get Started Labs"},sidebar:"mainSidebar",previous:{title:"Activation",permalink:"/docs/get-started/activation"},next:{title:"Overview",permalink:"/docs/for-ops/console/overview"}},s={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Building images",id:"building-images",level:2},{value:"Deploy application workloads",id:"deploy-application-workloads",level:2},{value:"Secure",id:"secure",level:2},{value:"Expose",id:"expose",level:2},{value:"Monitor",id:"monitor",level:2}],u={toc:p};function m(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Welcome to Otomi! If you are a developer and are going to use Otomi Platform, these getting started labs are for you. Step by step we'll guide you in using Otomi to deploy and manage your containerized applications. The getting started with Otomi for developers contains a set of labs to cover the most common developer activities."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-1"},"Prerequisites")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-2"},"Access Otomi Console"))),(0,i.kt)("h2",{id:"building-images"},"Building images"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-3"},"Create a private Git repo")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-4"},"Create a CI (build) pipeline")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-5"},"Push container images to your private repo")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-6"},"Create builds using Otomi")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-26"},"Trigger builds")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-7"},"Scan your images for vulnerabilities"))),(0,i.kt)("h2",{id:"deploy-application-workloads"},"Deploy application workloads"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-8"},"Create secrets")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-10"},"BYO manifest to deploy a workload with ArgoCD")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-11"},"Configure ArgoCD image updater")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-12"},"Create workloads using BYO Helm charts")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-13"},"Create workloads using Otomi charts")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-24"},"Create a PostgreSQL database"))),(0,i.kt)("h2",{id:"secure"},"Secure"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-15"},"Check policy compliance")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-17"},"Scan your running containers for vulnerabilities"))),(0,i.kt)("h2",{id:"expose"},"Expose"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-18"},"Publicly expose a service")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-19"},"Configuring network policies"))),(0,i.kt)("h2",{id:"monitor"},"Monitor"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-20"},"View container logs")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-21"},"View container metrics")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-22"},"Monitor custom metrics")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-23"},"Monitoring service availability")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"lab-25"},"Monitor databases"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/efe7c983.e2e3aa58.js b/assets/js/efe7c983.2909da42.js similarity index 98% rename from assets/js/efe7c983.e2e3aa58.js rename to assets/js/efe7c983.2909da42.js index a9fe45161..ac77b6a53 100644 --- a/assets/js/efe7c983.e2e3aa58.js +++ b/assets/js/efe7c983.2909da42.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[6299],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>c});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var p=a.createContext({}),u=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=u(e.components);return a.createElement(p.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=u(r),c=n,f=m["".concat(p,".").concat(c)]||m[c]||d[c]||o;return r?a.createElement(f,i(i({ref:t},s),{},{components:r})):a.createElement(f,i({ref:t},s))}));function c(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:n,i[1]=l;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var a=r(7462),n=(r(7294),r(3905));const o={slug:"roadmap",title:"Product Roadmap",sidebar_label:"Roadmap"},i="Supported Kubernetes version",l={unversionedId:"roadmap",id:"roadmap",title:"Product Roadmap",description:"We are dedicated to maintain support for three different Kubernetes versions within a specific major version of Otomi. Whenever we decide to discontinue support for a particular Kubernetes version, we increment the major version of Otomi.",source:"@site/product/roadmap.md",sourceDirName:".",slug:"/roadmap",permalink:"/product/roadmap",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/roadmap.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"roadmap",title:"Product Roadmap",sidebar_label:"Roadmap"},sidebar:"mainSidebar",previous:{title:"Otomi Projects",permalink:"/product/architecture"},next:{title:"FAQ",permalink:"/product/faq"}},p={},u=[{value:"2023 Q4",id:"2023-q4",level:2},{value:"2024 Q1",id:"2024-q1",level:2},{value:"2024 Q2",id:"2024-q2",level:2},{value:"After Q2 2024",id:"after-q2-2024",level:2}],s={toc:u};function d(e){let{components:t,...r}=e;return(0,n.kt)("wrapper",(0,a.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"supported-kubernetes-version"},"Supported Kubernetes version"),(0,n.kt)("p",null,"We are dedicated to maintain support for three different Kubernetes versions within a specific major version of Otomi. Whenever we decide to discontinue support for a particular Kubernetes version, we increment the major version of Otomi."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Otomi Version"),(0,n.kt)("th",{parentName:"tr",align:null},"Supported Kubernetes version"),(0,n.kt)("th",{parentName:"tr",align:null},"Expected date"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"v1.0.0"),(0,n.kt)("td",{parentName:"tr",align:null},"1.25, 1.26, 1.27"),(0,n.kt)("td",{parentName:"tr",align:null},"2023-09-28")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"v2.0.0"),(0,n.kt)("td",{parentName:"tr",align:null},"1.26, 1.27, 1.28"),(0,n.kt)("td",{parentName:"tr",align:null},"2024-02-28")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"v3.0.0"),(0,n.kt)("td",{parentName:"tr",align:null},"1.27, 1.28, 1.29"),(0,n.kt)("td",{parentName:"tr",align:null},"2024-05-28")))),(0,n.kt)("h1",{id:"roadmap"},"Roadmap"),(0,n.kt)("h2",{id:"2023-q4"},"2023 Q4"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Provide a default workload catalog in Gitea"),(0,n.kt)("li",{parentName:"ul"},"Migrate platform pipeline from Drone to Tekton"),(0,n.kt)("li",{parentName:"ul"},"Leverage ArgoCD to deploy Otomi apps and Teams"),(0,n.kt)("li",{parentName:"ul"},"Quality assurance cluster for continuous Otomi hardening and performance test")),(0,n.kt)("h2",{id:"2024-q1"},"2024 Q1"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Implement status indicators within Otomi Console to keep Team users informed about the status of various components, including Build processes, Workload management, and Service availability"),(0,n.kt)("li",{parentName:"ul"},"Harden the Istio service mesh configuration"),(0,n.kt)("li",{parentName:"ul"},"Add support for ARM architecture"),(0,n.kt)("li",{parentName:"ul"},"Enable user configurable storage classes"),(0,n.kt)("li",{parentName:"ul"},"Implement Gitea with a database managed by the CloudNativePG operator"),(0,n.kt)("li",{parentName:"ul"},"Provide disaster recovery procedures for Otomi core applications, such as Gitea, Keycloak and Harbor"),(0,n.kt)("li",{parentName:"ul"},"New secret storage engine (a replacement for Hashicorp Vault)")),(0,n.kt)("h2",{id:"2024-q2"},"2024 Q2"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Add Team Dashboards to provide an overview of team resource status using Prometheus metrics"),(0,n.kt)("li",{parentName:"ul"},"Enhance network policies across the platform"),(0,n.kt)("li",{parentName:"ul"},"Establish separate Kubernetes namespaces for Team Applications"),(0,n.kt)("li",{parentName:"ul"},"Ensure Otomi's NSA and CISA compliance"),(0,n.kt)("li",{parentName:"ul"},"Provide Application specific dashboards")),(0,n.kt)("h2",{id:"after-q2-2024"},"After Q2 2024"),(0,n.kt)("p",null,"After Q2 2024 we have the following goals:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Make Otomi more plugable by enabling users to bring their own platform apps"),(0,n.kt)("li",{parentName:"ul"},"Offer more middleware services (like caching, message queuing, databases)"),(0,n.kt)("li",{parentName:"ul"},"Migrate to ambient mesh using eBPF"),(0,n.kt)("li",{parentName:"ul"},"Remove platform app forms in favor of generated values that can be customized in an editor")))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[6299],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>c});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var p=a.createContext({}),u=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=u(e.components);return a.createElement(p.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=u(r),c=n,f=m["".concat(p,".").concat(c)]||m[c]||d[c]||o;return r?a.createElement(f,i(i({ref:t},s),{},{components:r})):a.createElement(f,i({ref:t},s))}));function c(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:n,i[1]=l;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var a=r(7462),n=(r(7294),r(3905));const o={slug:"roadmap",title:"Product Roadmap",sidebar_label:"Roadmap"},i="Supported Kubernetes version",l={unversionedId:"roadmap",id:"roadmap",title:"Product Roadmap",description:"We are dedicated to maintain support for three different Kubernetes versions within a specific major version of Otomi. Whenever we decide to discontinue support for a particular Kubernetes version, we increment the major version of Otomi.",source:"@site/product/roadmap.md",sourceDirName:".",slug:"/roadmap",permalink:"/product/roadmap",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/roadmap.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"roadmap",title:"Product Roadmap",sidebar_label:"Roadmap"},sidebar:"mainSidebar",previous:{title:"Otomi Projects",permalink:"/product/architecture"},next:{title:"FAQ",permalink:"/product/faq"}},p={},u=[{value:"2023 Q4",id:"2023-q4",level:2},{value:"2024 Q1",id:"2024-q1",level:2},{value:"2024 Q2",id:"2024-q2",level:2},{value:"After Q2 2024",id:"after-q2-2024",level:2}],s={toc:u};function d(e){let{components:t,...r}=e;return(0,n.kt)("wrapper",(0,a.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"supported-kubernetes-version"},"Supported Kubernetes version"),(0,n.kt)("p",null,"We are dedicated to maintain support for three different Kubernetes versions within a specific major version of Otomi. Whenever we decide to discontinue support for a particular Kubernetes version, we increment the major version of Otomi."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Otomi Version"),(0,n.kt)("th",{parentName:"tr",align:null},"Supported Kubernetes version"),(0,n.kt)("th",{parentName:"tr",align:null},"Expected date"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"v1.0.0"),(0,n.kt)("td",{parentName:"tr",align:null},"1.25, 1.26, 1.27"),(0,n.kt)("td",{parentName:"tr",align:null},"2023-09-28")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"v2.0.0"),(0,n.kt)("td",{parentName:"tr",align:null},"1.26, 1.27, 1.28"),(0,n.kt)("td",{parentName:"tr",align:null},"2024-02-28")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"v3.0.0"),(0,n.kt)("td",{parentName:"tr",align:null},"1.27, 1.28, 1.29"),(0,n.kt)("td",{parentName:"tr",align:null},"2024-05-28")))),(0,n.kt)("h1",{id:"roadmap"},"Roadmap"),(0,n.kt)("h2",{id:"2023-q4"},"2023 Q4"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Provide a default workload catalog in Gitea"),(0,n.kt)("li",{parentName:"ul"},"Migrate platform pipeline from Drone to Tekton"),(0,n.kt)("li",{parentName:"ul"},"Leverage ArgoCD to deploy Otomi apps and Teams"),(0,n.kt)("li",{parentName:"ul"},"Quality assurance cluster for continuous Otomi hardening and performance test")),(0,n.kt)("h2",{id:"2024-q1"},"2024 Q1"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Implement status indicators within Otomi Console to keep Team users informed about the status of various components, including Build processes, Workload management, and Service availability"),(0,n.kt)("li",{parentName:"ul"},"Harden the Istio service mesh configuration"),(0,n.kt)("li",{parentName:"ul"},"Add support for ARM architecture"),(0,n.kt)("li",{parentName:"ul"},"Enable user configurable storage classes"),(0,n.kt)("li",{parentName:"ul"},"Implement Gitea with a database managed by the CloudNativePG operator"),(0,n.kt)("li",{parentName:"ul"},"Provide disaster recovery procedures for Otomi core applications, such as Gitea, Keycloak and Harbor"),(0,n.kt)("li",{parentName:"ul"},"New secret storage engine (a replacement for Hashicorp Vault)")),(0,n.kt)("h2",{id:"2024-q2"},"2024 Q2"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Add Team Dashboards to provide an overview of team resource status using Prometheus metrics"),(0,n.kt)("li",{parentName:"ul"},"Enhance network policies across the platform"),(0,n.kt)("li",{parentName:"ul"},"Establish separate Kubernetes namespaces for Team Applications"),(0,n.kt)("li",{parentName:"ul"},"Ensure Otomi's NSA and CISA compliance"),(0,n.kt)("li",{parentName:"ul"},"Provide Application specific dashboards")),(0,n.kt)("h2",{id:"after-q2-2024"},"After Q2 2024"),(0,n.kt)("p",null,"After Q2 2024 we have the following goals:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Make Otomi more plugable by enabling users to bring their own platform apps"),(0,n.kt)("li",{parentName:"ul"},"Offer more middleware services (like caching, message queuing, databases)"),(0,n.kt)("li",{parentName:"ul"},"Migrate to ambient mesh using eBPF"),(0,n.kt)("li",{parentName:"ul"},"Remove platform app forms in favor of generated values that can be customized in an editor")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f1abdd8c.390ae031.js b/assets/js/f1abdd8c.6bfde2e2.js similarity index 98% rename from assets/js/f1abdd8c.390ae031.js rename to assets/js/f1abdd8c.6bfde2e2.js index b6c33d87c..328dfcfde 100644 --- a/assets/js/f1abdd8c.390ae031.js +++ b/assets/js/f1abdd8c.6bfde2e2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[6779],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),u=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=u(n),d=o,h=m["".concat(s,".").concat(d)]||m[d]||c[d]||i;return n?a.createElement(h,r(r({ref:t},p),{},{components:n})):a.createElement(h,r({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,r[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>u});var a=n(7462),o=(n(7294),n(3905));const i={slug:"faq",title:"FAQ"},r=void 0,l={unversionedId:"faq",id:"faq",title:"FAQ",description:"More about Otomi",source:"@site/product/faq.md",sourceDirName:".",slug:"/faq",permalink:"/product/faq",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/faq.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1696965024,formattedLastUpdatedAt:"Oct 10, 2023",frontMatter:{slug:"faq",title:"FAQ"},sidebar:"mainSidebar",previous:{title:"Roadmap",permalink:"/product/roadmap"},next:{title:"Overview",permalink:"/product/use-cases/overview"}},s={},u=[{value:"More about Otomi",id:"more-about-otomi",level:2},{value:"Setup and Installation",id:"setup-and-installation",level:2},{value:"Other",id:"other",level:2}],p={toc:u};function c(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"more-about-otomi"},"More about Otomi"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Is Otomi a lightweight version of Rancher or OpenShift"),(0,o.kt)("p",null,"We understand that products like Rancher and OpenShift all propagate that they ship with integrated tools, but we take the term integrated a little more serious. Within Otomi, integrated means applications are pre-configured with Otomi default configuration values, applications have been adjusted to comply with all Otomi security policies, and applications have been made user-aware (using OIDC) and multi-tenant."),(0,o.kt)("p",null,"Otomi can NOT be used to provision and manage Kubernetes clusters. Otomi is an application stack on top of Kubernetes that can be installed with a Helm chart, and offers a complete suite of integrated and pre-configured applications combined with automation and developer self-service. Another huge difference compared to OpenShift and Rancher is that everything in Otomi is reflected in code and stored in Git.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Is Otomi some kind of Kubeapps"),(0,o.kt)("p",null,"We can imagine when looking at the list of all pre-configured and ready-to-use apps, you might get the impression that Otomi is some kind of application catalog for Kubernetes. But the opposite is true. When you install Otomi, you will get all of these apps and they\u2019re already configured for you, and they will work out-of-the-box. You can then use the web UI or values repository to adjust the configuration of these apps based on your own requirements.")),(0,o.kt)("h2",{id:"setup-and-installation"},"Setup and Installation"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"What are the minimal requirements to install Otomi?"),(0,o.kt)("p",null,"Otomi requires a running Kubernetes cluster of version ",(0,o.kt)("inlineCode",{parentName:"p"},"1.24")," up to ",(0,o.kt)("inlineCode",{parentName:"p"},"1.25")," using a Node pool with at least ",(0,o.kt)("inlineCode",{parentName:"p"},"6 vCPU")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"8 GiB memory"),", but more is recommended. When using the ",(0,o.kt)("inlineCode",{parentName:"p"},"custom")," provider (when installing Kubernetes on a unsupported provider), make sure Otomi can create a K8s LoadBalancer Service that is accessible from your machine (but not using 127.0.0.1).")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Is the Quickstart the only way to install Otomi?"),(0,o.kt)("p",null,"No. The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/redkubes/quickstart"},"otomi-quickstart")," uses Terraform to provision a three-node Kubernetes cluster in AWS, Azure, or GCP and installs Otomi. You can also provision a Kubernetes cluster yourself and install Otomi using the Helm chart. Check ",(0,o.kt)("a",{parentName:"p",href:"/docs/get-started/installation#install-otomi-with-helm"},"chart-install")," for more details.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Where can I find all possible configuration options for Otomi?"),(0,o.kt)("p",null,"When installing Otomi with the helm chart you can find its ",(0,o.kt)("inlineCode",{parentName:"p"},"values-schema.json")," inside, which contains all the possible configuration parameters. It is generated from ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/redkubes/otomi-core/blob/main/values-schema.yaml"},"otomi-core/values-schema.yaml"),".")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Can Otomi be deployed on an existing cluster?"),(0,o.kt)("p",null,"Yes, Otomi can be installed on any cluster as long as there are no namespaces that are also created by Otomi.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Can I install Otomi without using a DNS zone?"),(0,o.kt)("p",null,"Yes, using a DNS zone for name resolution is optional. When installing Otomi with minimal values, nip.io is used for name resolution pointing to the public IP of the cloud load balancer.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"I don't have an external IdP like Azure AD. Can I still install Otomi?"),(0,o.kt)("p",null,"Yes, using an external IdP like Azure AD is optional. When installing Otomi with minimal values (no optional configuration), Otomi will configure Keycloak as an IdP. You can create users in Keycloak and assign them to the pre-configured roles.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Can I install Otomi on my laptop using Minikube?"),(0,o.kt)("p",null,"Yes. You can use the Otomi ",(0,o.kt)("inlineCode",{parentName:"p"},"custom")," provider to install Otomi on Kubernetes running on your own hardware, including Minikube. Note that Otomi needs to be able to create a Kubernetes LoadBalancer service and the IP needs to be accessible for pods running in the cluster and for your local browser. ",(0,o.kt)("inlineCode",{parentName:"p"},"127.0.0.1")," can not be used, so running minikube with the Docker provider is not supported. Use the ",(0,o.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/drivers/hyperkit/"},"Hyperkit driver")," instead.")),(0,o.kt)("h2",{id:"other"},"Other"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Do you provide commercial support?"),(0,o.kt)("p",null,"Yes, you can contact us for commercial support. ",(0,o.kt)("a",{parentName:"p",href:"https://redkubes.com"},"Red Kubes")," is the company behind Otomi.")))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[6779],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),u=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=u(n),d=o,h=m["".concat(s,".").concat(d)]||m[d]||c[d]||i;return n?a.createElement(h,r(r({ref:t},p),{},{components:n})):a.createElement(h,r({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,r[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>u});var a=n(7462),o=(n(7294),n(3905));const i={slug:"faq",title:"FAQ"},r=void 0,l={unversionedId:"faq",id:"faq",title:"FAQ",description:"More about Otomi",source:"@site/product/faq.md",sourceDirName:".",slug:"/faq",permalink:"/product/faq",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/edit/main/product/faq.md",tags:[],version:"current",lastUpdatedBy:"Sander Rodenhuis",lastUpdatedAt:1697013916,formattedLastUpdatedAt:"Oct 11, 2023",frontMatter:{slug:"faq",title:"FAQ"},sidebar:"mainSidebar",previous:{title:"Roadmap",permalink:"/product/roadmap"},next:{title:"Overview",permalink:"/product/use-cases/overview"}},s={},u=[{value:"More about Otomi",id:"more-about-otomi",level:2},{value:"Setup and Installation",id:"setup-and-installation",level:2},{value:"Other",id:"other",level:2}],p={toc:u};function c(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"more-about-otomi"},"More about Otomi"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Is Otomi a lightweight version of Rancher or OpenShift"),(0,o.kt)("p",null,"We understand that products like Rancher and OpenShift all propagate that they ship with integrated tools, but we take the term integrated a little more serious. Within Otomi, integrated means applications are pre-configured with Otomi default configuration values, applications have been adjusted to comply with all Otomi security policies, and applications have been made user-aware (using OIDC) and multi-tenant."),(0,o.kt)("p",null,"Otomi can NOT be used to provision and manage Kubernetes clusters. Otomi is an application stack on top of Kubernetes that can be installed with a Helm chart, and offers a complete suite of integrated and pre-configured applications combined with automation and developer self-service. Another huge difference compared to OpenShift and Rancher is that everything in Otomi is reflected in code and stored in Git.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Is Otomi some kind of Kubeapps"),(0,o.kt)("p",null,"We can imagine when looking at the list of all pre-configured and ready-to-use apps, you might get the impression that Otomi is some kind of application catalog for Kubernetes. But the opposite is true. When you install Otomi, you will get all of these apps and they\u2019re already configured for you, and they will work out-of-the-box. You can then use the web UI or values repository to adjust the configuration of these apps based on your own requirements.")),(0,o.kt)("h2",{id:"setup-and-installation"},"Setup and Installation"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"What are the minimal requirements to install Otomi?"),(0,o.kt)("p",null,"Otomi requires a running Kubernetes cluster of version ",(0,o.kt)("inlineCode",{parentName:"p"},"1.24")," up to ",(0,o.kt)("inlineCode",{parentName:"p"},"1.25")," using a Node pool with at least ",(0,o.kt)("inlineCode",{parentName:"p"},"6 vCPU")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"8 GiB memory"),", but more is recommended. When using the ",(0,o.kt)("inlineCode",{parentName:"p"},"custom")," provider (when installing Kubernetes on a unsupported provider), make sure Otomi can create a K8s LoadBalancer Service that is accessible from your machine (but not using 127.0.0.1).")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Is the Quickstart the only way to install Otomi?"),(0,o.kt)("p",null,"No. The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/redkubes/quickstart"},"otomi-quickstart")," uses Terraform to provision a three-node Kubernetes cluster in AWS, Azure, or GCP and installs Otomi. You can also provision a Kubernetes cluster yourself and install Otomi using the Helm chart. Check ",(0,o.kt)("a",{parentName:"p",href:"/docs/get-started/installation#install-otomi-with-helm"},"chart-install")," for more details.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Where can I find all possible configuration options for Otomi?"),(0,o.kt)("p",null,"When installing Otomi with the helm chart you can find its ",(0,o.kt)("inlineCode",{parentName:"p"},"values-schema.json")," inside, which contains all the possible configuration parameters. It is generated from ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/redkubes/otomi-core/blob/main/values-schema.yaml"},"otomi-core/values-schema.yaml"),".")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Can Otomi be deployed on an existing cluster?"),(0,o.kt)("p",null,"Yes, Otomi can be installed on any cluster as long as there are no namespaces that are also created by Otomi.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Can I install Otomi without using a DNS zone?"),(0,o.kt)("p",null,"Yes, using a DNS zone for name resolution is optional. When installing Otomi with minimal values, nip.io is used for name resolution pointing to the public IP of the cloud load balancer.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"I don't have an external IdP like Azure AD. Can I still install Otomi?"),(0,o.kt)("p",null,"Yes, using an external IdP like Azure AD is optional. When installing Otomi with minimal values (no optional configuration), Otomi will configure Keycloak as an IdP. You can create users in Keycloak and assign them to the pre-configured roles.")),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Can I install Otomi on my laptop using Minikube?"),(0,o.kt)("p",null,"Yes. You can use the Otomi ",(0,o.kt)("inlineCode",{parentName:"p"},"custom")," provider to install Otomi on Kubernetes running on your own hardware, including Minikube. Note that Otomi needs to be able to create a Kubernetes LoadBalancer service and the IP needs to be accessible for pods running in the cluster and for your local browser. ",(0,o.kt)("inlineCode",{parentName:"p"},"127.0.0.1")," can not be used, so running minikube with the Docker provider is not supported. Use the ",(0,o.kt)("a",{parentName:"p",href:"https://minikube.sigs.k8s.io/docs/drivers/hyperkit/"},"Hyperkit driver")," instead.")),(0,o.kt)("h2",{id:"other"},"Other"),(0,o.kt)("details",null,(0,o.kt)("summary",null,"Do you provide commercial support?"),(0,o.kt)("p",null,"Yes, you can contact us for commercial support. ",(0,o.kt)("a",{parentName:"p",href:"https://redkubes.com"},"Red Kubes")," is the company behind Otomi.")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fea5e681.aed74c1a.js b/assets/js/fea5e681.f5ef62b0.js similarity index 61% rename from assets/js/fea5e681.aed74c1a.js rename to assets/js/fea5e681.f5ef62b0.js index 758181e38..a2f9ad0aa 100644 --- a/assets/js/fea5e681.aed74c1a.js +++ b/assets/js/fea5e681.f5ef62b0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[9806],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),f=a,m=d["".concat(l,".").concat(f)]||d[f]||p[f]||o;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={slug:"lab-7",title:"Scan your images for vulnerabilities",sidebar_label:"Scan images"},i=void 0,s={unversionedId:"for-devs/get-started/lab-7",id:"for-devs/get-started/lab-7",title:"Scan your images for vulnerabilities",description:"When your team is using Harbor for private image registries, you can use Trivy to automatically scan your images on push. This is not enabled by default. Ask your platform administrator to turn this on for your project in Harbor. When enabled, you can see the results of the scans by following these steps:",source:"@site/docs/for-devs/get-started/lab-7.md",sourceDirName:"for-devs/get-started",slug:"/for-devs/get-started/lab-7",permalink:"/docs/for-devs/get-started/lab-7",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/tree/main/docs/for-devs/get-started/lab-7.md",tags:[],version:"current",frontMatter:{slug:"lab-7",title:"Scan your images for vulnerabilities",sidebar_label:"Scan images"},sidebar:"mainSidebar",previous:{title:"Build images with Otomi",permalink:"/docs/for-devs/get-started/lab-6"},next:{title:"Create secrets",permalink:"/docs/for-devs/get-started/lab-8"}},l={},c=[],u={toc:c};function p(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"When your team is using Harbor for private image registries, you can use Trivy to automatically scan your images on push. This is not enabled by default. Ask your platform administrator to turn this on for your project in Harbor. When enabled, you can see the results of the scans by following these steps:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"In the apps section in Otomi console, click on Harbor"),(0,a.kt)("li",{parentName:"ul"},"Click on your project. You will only see the projects of the Teams that you are a member of"),(0,a.kt)("li",{parentName:"ul"},"You will now see a list of the teams repositories"),(0,a.kt)("li",{parentName:"ul"},"Click on the repository that contains the artifact (image) that you would like to investigate"),(0,a.kt)("li",{parentName:"ul"},"In the list of artifacts, you can see a summary of the scan results")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"kubecfg",src:r(8699).Z,width:"2814",height:"1382"})),(0,a.kt)("p",null,"When you click on the scanned artifact, you'll see a more detailed report on all the vulnerabilities:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"kubecfg",src:r(1603).Z,width:"2274",height:"822"})))}p.isMDXComponent=!0},1603:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/trivy-scan-details-e2e9f5ec44381db8ed6e520dc98e0726.png"},8699:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/trivy-scan-sum-476dc498cf7eb6c2ebcdbe1eacfa7ea3.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[9806],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(r),f=a,b=d["".concat(l,".").concat(f)]||d[f]||p[f]||o;return r?n.createElement(b,i(i({ref:t},u),{},{components:r})):n.createElement(b,i({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={slug:"lab-7",title:"Scan your images for vulnerabilities",sidebar_label:"Scan images"},i=void 0,s={unversionedId:"for-devs/get-started/lab-7",id:"for-devs/get-started/lab-7",title:"Scan your images for vulnerabilities",description:"When your team is using Harbor for private image registries, you can use Trivy to automatically scan your images on push. This is not enabled by default. Ask your platform administrator to turn this on for your project in Harbor. When enabled, you can see the results of the scans by following these steps:",source:"@site/docs/for-devs/get-started/lab-7.md",sourceDirName:"for-devs/get-started",slug:"/for-devs/get-started/lab-7",permalink:"/docs/for-devs/get-started/lab-7",draft:!1,editUrl:"https://github.com/redkubes/redkubes.github.io/tree/main/docs/for-devs/get-started/lab-7.md",tags:[],version:"current",frontMatter:{slug:"lab-7",title:"Scan your images for vulnerabilities",sidebar_label:"Scan images"},sidebar:"mainSidebar",previous:{title:"Trigger builds",permalink:"/docs/for-devs/get-started/lab-26"},next:{title:"Create secrets",permalink:"/docs/for-devs/get-started/lab-8"}},l={},c=[],u={toc:c};function p(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"When your team is using Harbor for private image registries, you can use Trivy to automatically scan your images on push. This is not enabled by default. Ask your platform administrator to turn this on for your project in Harbor. When enabled, you can see the results of the scans by following these steps:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"In the apps section in Otomi console, click on Harbor"),(0,a.kt)("li",{parentName:"ul"},"Click on your project. You will only see the projects of the Teams that you are a member of"),(0,a.kt)("li",{parentName:"ul"},"You will now see a list of the teams repositories"),(0,a.kt)("li",{parentName:"ul"},"Click on the repository that contains the artifact (image) that you would like to investigate"),(0,a.kt)("li",{parentName:"ul"},"In the list of artifacts, you can see a summary of the scan results")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"kubecfg",src:r(8699).Z,width:"2814",height:"1382"})),(0,a.kt)("p",null,"When you click on the scanned artifact, you'll see a more detailed report on all the vulnerabilities:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"kubecfg",src:r(1603).Z,width:"2274",height:"822"})))}p.isMDXComponent=!0},1603:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/trivy-scan-details-e2e9f5ec44381db8ed6e520dc98e0726.png"},8699:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/trivy-scan-sum-476dc498cf7eb6c2ebcdbe1eacfa7ea3.png"}}]); \ No newline at end of file diff --git a/assets/js/main.949bd71e.js b/assets/js/main.949bd71e.js deleted file mode 100644 index 6506bf814..000000000 --- a/assets/js/main.949bd71e.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.949bd71e.js.LICENSE.txt */ -(self.webpackChunkredkubes_github_io=self.webpackChunkredkubes_github_io||[]).push([[179],{830:(e,t,n)=>{"use strict";n.d(t,{W:()=>o});var r=n(7294);function o(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(7462),a=n(8356),i=n.n(a),s=n(6887);const l={"00210a32":[()=>n.e(2098).then(n.bind(n,1909)),"@site/docs/apps/gitea.md",1909],"03608398":[()=>n.e(8367).then(n.bind(n,8536)),"@site/docs/tutorials/overview.md",8536],"042c512d":[()=>n.e(2018).then(n.bind(n,5217)),"@site/product/use-cases/multi-cluster.md",5217],"052260a8":[()=>n.e(3272).then(n.bind(n,9098)),"@site/docs/for-ops/cli/encrypt.md",9098],"08d8079e":[()=>n.e(7683).then(n.t.bind(n,3769,19)),"/home/runner/work/redkubes.github.io/redkubes.github.io/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"09735fc0":[()=>n.e(1591).then(n.bind(n,1990)),"@site/docs/apps/jaeger.md",1990],"0be2dc55":[()=>n.e(8392).then(n.bind(n,7760)),"@site/docs/for-ops/cli/template.md",7760],"0c3fdeeb":[()=>n.e(6096).then(n.bind(n,821)),"@site/docs/for-ops/console/overview.md",821],"0d519d5d":[()=>n.e(634).then(n.bind(n,1158)),"@site/docs/for-devs/console/deploy-changes.md",1158],10959509:[()=>n.e(2704).then(n.bind(n,2444)),"@site/docs/for-ops/sre/troubleshooting.md",2444],"13689ae4":[()=>n.e(3576).then(n.bind(n,3044)),"@site/docs/for-ops/console/backups.md",3044],"14bc3799":[()=>n.e(2722).then(n.bind(n,6095)),"@site/docs/for-ops/cli/bootstrap.md",6095],"1691c9ac":[()=>n.e(6547).then(n.bind(n,7367)),"@site/docs/for-ops/console/clusters.md",7367],"17725d1c":[()=>n.e(8052).then(n.bind(n,3180)),"@site/docs/for-ops/console/policies.md",3180],17896441:[()=>Promise.all([n.e(532),n.e(7918)]).then(n.bind(n,93)),"@theme/DocItem",93],"17a7c5fe":[()=>n.e(3126).then(n.bind(n,3558)),"@site/docs/for-ops/console/settings/key-management.md",3558],"1830c2e3":[()=>n.e(1195).then(n.bind(n,7516)),"@site/docs/apps/certmanager.md",7516],"188da18d":[()=>n.e(2430).then(n.bind(n,9205)),"@site/docs/apps/trivy.md",9205],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,6675)),"@theme/SearchPage",6675],"1afc8419":[()=>n.e(8344).then(n.bind(n,2786)),"@site/docs/for-ops/sre/overview.md",2786],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1c28c6e3":[()=>n.e(9464).then(n.bind(n,4262)),"@site/docs/get-started/installation.md",4262],"1d3542c3":[()=>n.e(4473).then(n.bind(n,8448)),"@site/docs/for-ops/console/settings/smtp.md",8448],"1d911987":[()=>n.e(912).then(n.bind(n,2699)),"@site/docs/for-ops/console/settings/ingress.md",2699],"1dcded0d":[()=>n.e(7282).then(n.bind(n,9679)),"@site/docs/apps/grafana.md",9679],"1df93b7f":[()=>Promise.all([n.e(532),n.e(3237)]).then(n.bind(n,5206)),"@site/src/pages/index.tsx",5206],"1f25a778":[()=>n.e(7927).then(n.bind(n,2127)),"@site/docs/tutorials/tutorial-3.md",2127],"1f668492":[()=>n.e(2237).then(n.bind(n,4202)),"@site/docs/apps/falco.md",4202],"20c7dd93":[()=>n.e(4882).then(n.bind(n,7297)),"@site/docs/tutorials/tutorial-4.md",7297],"2138c50d":[()=>n.e(5389).then(n.bind(n,1539)),"@site/docs/for-devs/get-started/lab-22.md",1539],"21fbcd7c":[()=>n.e(3563).then(n.bind(n,8302)),"@site/product/architecture.md",8302],"2a1f96be":[()=>n.e(192).then(n.bind(n,1881)),"@site/docs/tutorials/tutorial-8.md",1881],"2a3fc902":[()=>n.e(4655).then(n.bind(n,2469)),"@site/docs/for-ops/how-to/use-team-admin.md",2469],"2cebb9b1":[()=>n.e(315).then(n.bind(n,4172)),"@site/docs/for-devs/get-started/lab-17.md",4172],"2d9c895d":[()=>n.e(5022).then(n.bind(n,1781)),"@site/product/use-cases/overview.md",1781],"2df7e88d":[()=>n.e(8607).then(n.bind(n,6368)),"@site/docs/for-ops/cli/sync.md",6368],"2f26dbd7":[()=>n.e(4041).then(n.bind(n,1693)),"@site/docs/for-ops/console/shortcuts.md",1693],"306a8c6c":[()=>n.e(7616).then(n.t.bind(n,9479,19)),"~docs/community/version-current-metadata-prop-751.json",9479],"30f4d83c":[()=>n.e(8129).then(n.bind(n,4088)),"@site/docs/for-devs/console/shell.md",4088],"3379d6c0":[()=>n.e(5195).then(n.bind(n,6610)),"@site/docs/for-ops/console/settings/dns.md",6610],"35ac0aef":[()=>n.e(1104).then(n.t.bind(n,2481,19)),"/home/runner/work/redkubes.github.io/redkubes.github.io/.docusaurus/docusaurus-plugin-content-docs/community/plugin-route-context-module-100.json",2481],"3765f133":[()=>n.e(7514).then(n.bind(n,2072)),"@site/docs/for-devs/console/shortcuts.md",2072],"3829398f":[()=>n.e(8379).then(n.bind(n,9174)),"@site/docs/for-ops/sre/upgrades.md",9174],"386e030b":[()=>n.e(7878).then(n.bind(n,1484)),"@site/docs/apps/kiali.md",1484],"39901f0d":[()=>n.e(6906).then(n.bind(n,9203)),"@site/docs/for-ops/console/secrets.md",9203],"39dd6d9c":[()=>n.e(8621).then(n.bind(n,5858)),"@site/docs/for-devs/get-started/lab-10.md",5858],"3a0feb37":[()=>n.e(4825).then(n.bind(n,7248)),"@site/docs/for-ops/how-to/switch-to-dns.md",7248],"3c110fea":[()=>n.e(2780).then(n.bind(n,7325)),"@site/docs/for-ops/console/settings/backup.md",7325],"3ca1c20f":[()=>n.e(3458).then(n.bind(n,6399)),"@site/docs/tutorials/tutorial-create-otomi-ksvc.md",6399],"3d235714":[()=>n.e(2117).then(n.bind(n,1398)),"@site/product/use-cases/adoption-framework.md",1398],"3e78db60":[()=>n.e(5001).then(n.bind(n,4866)),"@site/docs/for-devs/get-started/lab-18.md",4866],"3fd50427":[()=>n.e(3418).then(n.bind(n,8505)),"@site/docs/for-ops/console/deploy-changes.md",8505],"4380e181":[()=>n.e(1113).then(n.bind(n,8506)),"@site/docs/apps/loki.md",8506],"443e3a65":[()=>n.e(1254).then(n.bind(n,9966)),"@site/docs/for-ops/console/teams.md",9966],"46a4fdf9":[()=>n.e(5775).then(n.bind(n,4978)),"@site/docs/for-devs/console/projects.md",4978],"46be4bcd":[()=>n.e(7973).then(n.bind(n,4316)),"@site/docs/for-devs/console/workloads.md",4316],"4e07f80c":[()=>n.e(7894).then(n.bind(n,4354)),"@site/docs/for-devs/get-started/lab-1.md",4354],"4f01d7c7":[()=>n.e(7015).then(n.bind(n,3918)),"@site/product/introduction.md",3918],52898320:[()=>n.e(2832).then(n.bind(n,2924)),"@site/docs/apps/kubeclarity.md",2924],"541249eb":[()=>n.e(8696).then(n.bind(n,6419)),"@site/docs/for-ops/cli/diff.md",6419],"58c0f673":[()=>n.e(7097).then(n.bind(n,3223)),"@site/docs/for-devs/get-started/lab-8.md",3223],"59a7de32":[()=>n.e(9892).then(n.bind(n,81)),"@site/docs/tutorials/tutorial-9.md",81],"5c5eecab":[()=>n.e(4559).then(n.bind(n,3372)),"@site/docs/for-ops/cli/status.md",3372],"5c816f45":[()=>n.e(1957).then(n.bind(n,3059)),"@site/docs/for-devs/get-started/lab-16.md",3059],"5ce65c80":[()=>n.e(2280).then(n.bind(n,9941)),"@site/docs/for-ops/cli/installation.md",9941],"5cecd17a":[()=>n.e(7622).then(n.bind(n,7619)),"@site/docs/tutorials/tutorial-use-secrets.md",7619],"5db37859":[()=>n.e(344).then(n.bind(n,6797)),"@site/community/expectations.md",6797],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"5f4e8093":[()=>n.e(3942).then(n.bind(n,7709)),"@site/docs/for-ops/console/workloads.md",7709],"6269c3fd":[()=>n.e(8061).then(n.bind(n,3803)),"@site/docs/for-devs/get-started/lab-9.md",3803],"62b9025a":[()=>n.e(4542).then(n.bind(n,505)),"@site/docs/for-ops/how-to/install-with-dns.md",505],"646a49d4":[()=>n.e(5720).then(n.bind(n,3701)),"@site/docs/for-ops/cli/commit.md",3701],"66c551f1":[()=>n.e(8442).then(n.bind(n,4762)),"@site/docs/tutorials/tutorial-7.md",4762],"69fd0b9a":[()=>n.e(1730).then(n.bind(n,5232)),"@site/docs/for-ops/sre/daily.md",5232],"6c0258c8":[()=>n.e(8638).then(n.bind(n,3420)),"@site/docs/get-started/optional.md",3420],"6d553b82":[()=>n.e(4321).then(n.bind(n,7559)),"@site/docs/for-devs/console/services.md",7559],"70b0dc77":[()=>n.e(2515).then(n.bind(n,7881)),"@site/product/use-cases/edge.md",7881],73148982:[()=>n.e(1409).then(n.bind(n,7433)),"@site/product/eula/v1.md",7433],"734d54da":[()=>n.e(7778).then(n.t.bind(n,7085,19)),"/home/runner/work/redkubes.github.io/redkubes.github.io/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],"7c9f895f":[()=>n.e(27).then(n.bind(n,4462)),"@site/docs/for-devs/get-started/lab-13.md",4462],"7dfd3ef3":[()=>n.e(8049).then(n.bind(n,972)),"@site/docs/for-devs/get-started/lab-19.md",972],"7ea98ab3":[()=>n.e(9683).then(n.bind(n,6176)),"@site/docs/for-ops/console/apps.md",6176],"81e06d7e":[()=>n.e(5824).then(n.bind(n,7981)),"@site/docs/apps/istio.md",7981],"81f8c379":[()=>n.e(2552).then(n.bind(n,1363)),"@site/docs/apps/gatekeeper.md",1363],"8213a342":[()=>n.e(1882).then(n.bind(n,3910)),"@site/docs/apps/vault.md",3910],"842ea3d4":[()=>n.e(2851).then(n.bind(n,3780)),"@site/docs/tutorials/tutorial-6.md",3780],"84b718dc":[()=>n.e(8801).then(n.bind(n,4374)),"@site/docs/tutorials/tutorial-create-byo-svc.md",4374],"924eaf32":[()=>n.e(2441).then(n.bind(n,5890)),"@site/docs/for-devs/get-started/lab-21.md",5890],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"94da8644":[()=>n.e(1056).then(n.bind(n,2725)),"@site/docs/tutorials/tutorial-5.md",2725],"96d3f3ac":[()=>n.e(1390).then(n.bind(n,4573)),"@site/docs/for-devs/console/apps.md",4573],98242336:[()=>n.e(5290).then(n.bind(n,539)),"@site/docs/for-ops/cli/validate-values.md",539],"9824b3d7":[()=>n.e(443).then(n.bind(n,660)),"@site/docs/for-devs/console/settings.md",660],"9899ea6d":[()=>n.e(8506).then(n.bind(n,2233)),"@site/docs/for-ops/console/settings/cluster.md",2233],"99018ea3":[()=>n.e(597).then(n.bind(n,981)),"@site/docs/for-ops/console/settings/azure.md",981],"9a44d6ca":[()=>n.e(2276).then(n.bind(n,2051)),"@site/docs/for-ciso/overview.md",2051],"9aa6eb6f":[()=>n.e(7114).then(n.bind(n,3507)),"@site/docs/for-devs/get-started/lab-12.md",3507],"9b2db8ea":[()=>n.e(8852).then(n.bind(n,3156)),"@site/docs/for-ops/cli/rotate-keys.md",3156],"9cb4274e":[()=>n.e(1391).then(n.bind(n,6173)),"@site/docs/for-ops/cli/lint.md",6173],"9f503b51":[()=>n.e(9449).then(n.bind(n,7626)),"@site/docs/for-ops/how-to/create-and-restore-backups.md",7626],a0650468:[()=>n.e(781).then(n.bind(n,4185)),"@site/docs/tutorials/tutorial-2.md",4185],a39a834c:[()=>n.e(7498).then(n.t.bind(n,5745,19)),"/home/runner/work/redkubes.github.io/redkubes.github.io/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],a3cca685:[()=>n.e(4791).then(n.bind(n,5840)),"@site/docs/for-ops/console/builds.md",5840],a3d159d0:[()=>n.e(1696).then(n.bind(n,2402)),"@site/docs/for-devs/get-started/lab-6.md",2402],a47e2810:[()=>n.e(7984).then(n.bind(n,7090)),"@site/docs/for-ops/console/services.md",7090],a6a14297:[()=>n.e(6866).then(n.bind(n,4869)),"@site/docs/apps/knative.md",4869],a722ee7a:[()=>n.e(1573).then(n.bind(n,6250)),"@site/docs/for-ops/console/shell.md",6250],a8f6b1c9:[()=>n.e(7581).then(n.bind(n,535)),"@site/docs/for-devs/get-started/lab-20.md",535],a92bb299:[()=>n.e(5092).then(n.t.bind(n,8427,19)),"~docs/product/version-current-metadata-prop-751.json",8427],a98f6d6a:[()=>n.e(8971).then(n.bind(n,3726)),"@site/docs/for-devs/get-started/lab-15.md",3726],aa3203ff:[()=>n.e(2144).then(n.bind(n,4394)),"@site/docs/for-devs/console/builds.md",4394],ac482592:[()=>n.e(1506).then(n.bind(n,6805)),"@site/docs/tutorials/tutorial-1.md",6805],acbd0412:[()=>n.e(7763).then(n.bind(n,7694)),"@site/docs/tutorials/tutorial-10.md",7694],ace391e9:[()=>n.e(4505).then(n.t.bind(n,3206,19)),"/home/runner/work/redkubes.github.io/redkubes.github.io/.docusaurus/docusaurus-plugin-content-docs/product/plugin-route-context-module-100.json",3206],af477ebb:[()=>n.e(8897).then(n.bind(n,4650)),"@site/docs/for-ops/cli/validate-templates.md",4650],af8b4e82:[()=>n.e(7444).then(n.bind(n,4453)),"@site/docs/apps/tekton.md",4453],af9df136:[()=>n.e(6888).then(n.bind(n,291)),"@site/docs/for-ops/cli/bash.md",291],afd24866:[()=>n.e(2370).then(n.bind(n,8181)),"@site/docs/apps/argocd.md",8181],afecbe3a:[()=>n.e(6190).then(n.bind(n,7499)),"@site/docs/for-devs/get-started/lab-2.md",7499],b04270fa:[()=>n.e(5920).then(n.bind(n,4915)),"@site/docs/apps/ingress-nginx.md",4915],b0500dc6:[()=>n.e(8185).then(n.bind(n,2278)),"@site/product/use-cases/multi-tenancy.md",2278],b3f57382:[()=>n.e(3846).then(n.bind(n,5693)),"@site/docs/for-devs/get-started/lab-25.md",5693],b458a144:[()=>n.e(2869).then(n.bind(n,6891)),"@site/docs/for-ops/console/settings/co-monitoring.md",6891],b4b7b186:[()=>n.e(3520).then(n.bind(n,1993)),"@site/product/use-cases/serverless.md",1993],bb6d4937:[()=>n.e(9637).then(n.bind(n,8502)),"@site/docs/get-started/activation.md",8502],bcbdbf75:[()=>n.e(6576).then(n.bind(n,3417)),"@site/docs/for-ops/cli/x.md",3417],bde17074:[()=>n.e(9237).then(n.bind(n,3057)),"@site/docs/apps/thanos.md",3057],be94a9c8:[()=>n.e(1854).then(n.bind(n,4447)),"@site/docs/for-ops/cli/deploying.md",4447],c0fcc3ac:[()=>n.e(3644).then(n.bind(n,5438)),"@site/docs/for-ops/cli/check-policies.md",5438],c1cd9779:[()=>n.e(1658).then(n.bind(n,6860)),"@site/community/code-of-conduct.md",6860],c3394322:[()=>n.e(9742).then(n.bind(n,4079)),"@site/docs/for-ops/cli/values.md",4079],c3428a3f:[()=>n.e(4729).then(n.bind(n,4280)),"@site/docs/get-started/chart.md",4280],c3a9c637:[()=>n.e(1576).then(n.bind(n,9451)),"@site/docs/apps/alertmanager.md",9451],c4d36760:[()=>n.e(8028).then(n.bind(n,2530)),"@site/docs/apps/external-dns.md",2530],c5c74bfd:[()=>n.e(5616).then(n.bind(n,4144)),"@site/docs/for-ops/console/settings/alerts.md",4144],c61e7c1f:[()=>n.e(4258).then(n.bind(n,6180)),"@site/docs/tutorials/tutorial-create-byo-ksvc.md",6180],c642c7e8:[()=>n.e(512).then(n.bind(n,3909)),"@site/community/welcome.md",3909],c78ef024:[()=>n.e(4115).then(n.bind(n,8848)),"@site/docs/apps/kubeapps.md",8848],c83d091b:[()=>n.e(5207).then(n.bind(n,4676)),"@site/docs/for-devs/get-started/lab-3.md",4676],c9644b78:[()=>n.e(537).then(n.bind(n,9089)),"@site/docs/for-ops/console/settings/oidc.md",9089],c9ff9b08:[()=>n.e(1913).then(n.bind(n,6200)),"@site/docs/for-ops/console/projects.md",6200],ca4242f5:[()=>n.e(5033).then(n.bind(n,2531)),"@site/docs/for-ops/cli/known-issues.md",2531],cd151fd5:[()=>n.e(3544).then(n.bind(n,206)),"@site/docs/apps/prometheus.md",206],cdbfcf31:[()=>n.e(1437).then(n.bind(n,766)),"@site/docs/for-devs/get-started/lab-23.md",766],d19eaffd:[()=>n.e(5531).then(n.bind(n,4348)),"@site/docs/for-devs/get-started/lab-5.md",4348],d2c0d625:[()=>n.e(1242).then(n.bind(n,4709)),"@site/docs/for-devs/get-started/lab-4.md",4709],d53aaf7f:[()=>n.e(965).then(n.bind(n,6401)),"@site/docs/for-ops/cli/apply.md",6401],d673e682:[()=>n.e(3120).then(n.bind(n,5282)),"@site/product/use-cases/ci-cd.md",5282],d76c6a89:[()=>n.e(4717).then(n.bind(n,5684)),"@site/docs/apps/harbor.md",5684],d8a040d1:[()=>n.e(2615).then(n.bind(n,5419)),"@site/docs/for-ops/cli/pull.md",5419],d9893b92:[()=>n.e(2668).then(n.bind(n,2617)),"@site/docs/for-ops/cli/destroy.md",2617],db2fd2f7:[()=>n.e(439).then(n.bind(n,8284)),"@site/docs/apps/minio.md",8284],db4c0e54:[()=>n.e(1713).then(n.bind(n,6778)),"@site/docs/for-devs/console/secrets.md",6778],df2434c5:[()=>n.e(767).then(n.bind(n,8396)),"@site/docs/apps/drone.md",8396],e216824f:[()=>n.e(9109).then(n.bind(n,1221)),"@site/docs/get-started/prerequisites.md",1221],e2cc03cb:[()=>n.e(1241).then(n.bind(n,634)),"@site/docs/for-ops/how-to/ingress-classes.md",634],e65ca800:[()=>n.e(6306).then(n.bind(n,552)),"@site/docs/for-ops/cli/decrypt.md",552],e6cdbc01:[()=>n.e(4027).then(n.bind(n,4583)),"@site/docs/for-ops/console/settings/otomi.md",4583],e7ee1f4e:[()=>n.e(4722).then(n.bind(n,5243)),"@site/docs/for-ops/how-to/core-only.md",5243],e878c199:[()=>n.e(2163).then(n.bind(n,8170)),"@site/community/values.md",8170],ed3faf6d:[()=>n.e(9153).then(n.bind(n,2998)),"@site/docs/apps/keycloak.md",2998],ee2e4fcc:[()=>n.e(8699).then(n.bind(n,3164)),"@site/docs/for-devs/get-started/lab-14.md",3164],efb16635:[()=>n.e(8773).then(n.bind(n,2630)),"@site/docs/for-devs/get-started/overview.md",2630],efe7c983:[()=>n.e(6299).then(n.bind(n,8645)),"@site/product/roadmap.md",8645],f1abdd8c:[()=>n.e(6779).then(n.bind(n,684)),"@site/product/faq.md",684],f34c6cc5:[()=>n.e(1515).then(n.bind(n,3181)),"@site/docs/apps/velero.md",3181],fcae0bab:[()=>n.e(9119).then(n.bind(n,795)),"@site/docs/for-devs/get-started/lab-11.md",795],fdf82bde:[()=>n.e(9846).then(n.bind(n,5958)),"@site/docs/for-devs/get-started/lab-24.md",5958],fea5e681:[()=>n.e(9806).then(n.bind(n,9841)),"@site/docs/for-devs/get-started/lab-7.md",9841],feda9f98:[()=>n.e(4011).then(n.bind(n,7034)),"@site/docs/for-ops/cli/test.md",7034]};function c(e){let{error:t,retry:n,pastDelay:o}=e;return t?r.createElement("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%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):o?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("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"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const a=s[`${e}-${t}`],p={},f=[],m=[],h=(0,u.Z)(a);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=l[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(a));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)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 o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let a=i;const s=n.split(".");s.slice(0,-1).forEach((e=>{a=a[e]})),a[s[s.length-1]]=o}));const s=i.__comp;delete i.__comp;const l=i.__context;return delete i.__context,r.createElement(d.z,{value:l},r.createElement(s,(0,o.Z)({},i,n)))}})}const f=[{path:"/search",component:p("/search","354"),exact:!0},{path:"/community",component:p("/community","313"),routes:[{path:"/community/code-of-conduct",component:p("/community/code-of-conduct","88e"),exact:!0,sidebar:"mainSidebar"},{path:"/community/community-values",component:p("/community/community-values","83d"),exact:!0,sidebar:"mainSidebar"},{path:"/community/expectations",component:p("/community/expectations","9e9"),exact:!0,sidebar:"mainSidebar"},{path:"/community/welcome",component:p("/community/welcome","87f"),exact:!0,sidebar:"mainSidebar"}]},{path:"/docs",component:p("/docs","daa"),routes:[{path:"/docs/apps/alertmanager",component:p("/docs/apps/alertmanager","5d5"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/argocd",component:p("/docs/apps/argocd","d53"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/certmanager",component:p("/docs/apps/certmanager","2e5"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/drone",component:p("/docs/apps/drone","98f"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/external-dns",component:p("/docs/apps/external-dns","412"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/falco",component:p("/docs/apps/falco","2b7"),exact:!0},{path:"/docs/apps/gatekeeper",component:p("/docs/apps/gatekeeper","960"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/gitea",component:p("/docs/apps/gitea","b47"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/grafana",component:p("/docs/apps/grafana","947"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/harbor",component:p("/docs/apps/harbor","b89"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/ingress-nginx",component:p("/docs/apps/ingress-nginx","4a8"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/istio",component:p("/docs/apps/istio","05b"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/jaeger",component:p("/docs/apps/jaeger","8a6"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/keycloak",component:p("/docs/apps/keycloak","316"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/kiali",component:p("/docs/apps/kiali","06b"),exact:!0},{path:"/docs/apps/knative",component:p("/docs/apps/knative","49e"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/kubeapps",component:p("/docs/apps/kubeapps","504"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/kubeclarity",component:p("/docs/apps/kubeclarity","2f7"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/loki",component:p("/docs/apps/loki","266"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/minio",component:p("/docs/apps/minio","804"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/prometheus",component:p("/docs/apps/prometheus","523"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/tekton",component:p("/docs/apps/tekton","2af"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/thanos",component:p("/docs/apps/thanos","b34"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/trivy",component:p("/docs/apps/trivy","323"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/vault",component:p("/docs/apps/vault","f81"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/apps/velero",component:p("/docs/apps/velero","2e5"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ciso/overview",component:p("/docs/for-ciso/overview","de6"),exact:!0},{path:"/docs/for-devs/console/apps",component:p("/docs/for-devs/console/apps","05b"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/builds",component:p("/docs/for-devs/console/builds","b55"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/deploy-changes",component:p("/docs/for-devs/console/deploy-changes","e7f"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/projects",component:p("/docs/for-devs/console/projects","140"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/secrets",component:p("/docs/for-devs/console/secrets","a74"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/services",component:p("/docs/for-devs/console/services","367"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/settings",component:p("/docs/for-devs/console/settings","898"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/shell",component:p("/docs/for-devs/console/shell","2e9"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/shortcuts",component:p("/docs/for-devs/console/shortcuts","2d4"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/console/workloads",component:p("/docs/for-devs/console/workloads","f60"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-1",component:p("/docs/for-devs/get-started/lab-1","64c"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-10",component:p("/docs/for-devs/get-started/lab-10","15f"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-11",component:p("/docs/for-devs/get-started/lab-11","ae0"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-12",component:p("/docs/for-devs/get-started/lab-12","ef8"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-13",component:p("/docs/for-devs/get-started/lab-13","14c"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-14",component:p("/docs/for-devs/get-started/lab-14","d6d"),exact:!0},{path:"/docs/for-devs/get-started/lab-15",component:p("/docs/for-devs/get-started/lab-15","800"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-16",component:p("/docs/for-devs/get-started/lab-16","187"),exact:!0},{path:"/docs/for-devs/get-started/lab-17",component:p("/docs/for-devs/get-started/lab-17","f5b"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-18",component:p("/docs/for-devs/get-started/lab-18","5bb"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-19",component:p("/docs/for-devs/get-started/lab-19","7bd"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-2",component:p("/docs/for-devs/get-started/lab-2","de2"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-20",component:p("/docs/for-devs/get-started/lab-20","17b"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-21",component:p("/docs/for-devs/get-started/lab-21","72d"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-22",component:p("/docs/for-devs/get-started/lab-22","665"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-23",component:p("/docs/for-devs/get-started/lab-23","a92"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-24",component:p("/docs/for-devs/get-started/lab-24","8d9"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-25",component:p("/docs/for-devs/get-started/lab-25","073"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-3",component:p("/docs/for-devs/get-started/lab-3","af8"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-4",component:p("/docs/for-devs/get-started/lab-4","03d"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-5",component:p("/docs/for-devs/get-started/lab-5","2a5"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-6",component:p("/docs/for-devs/get-started/lab-6","1d2"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-7",component:p("/docs/for-devs/get-started/lab-7","eac"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-8",component:p("/docs/for-devs/get-started/lab-8","b37"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-devs/get-started/lab-9",component:p("/docs/for-devs/get-started/lab-9","25d"),exact:!0},{path:"/docs/for-devs/get-started/overview",component:p("/docs/for-devs/get-started/overview","37d"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/apply",component:p("/docs/for-ops/cli/apply","f61"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/bash",component:p("/docs/for-ops/cli/bash","408"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/bootstrap",component:p("/docs/for-ops/cli/bootstrap","3a6"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/check-policies",component:p("/docs/for-ops/cli/check-policies","c28"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/commit",component:p("/docs/for-ops/cli/commit","8f3"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/decrypt",component:p("/docs/for-ops/cli/decrypt","e7f"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/deploying",component:p("/docs/for-ops/cli/deploying","b05"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/destroy",component:p("/docs/for-ops/cli/destroy","6ff"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/diff",component:p("/docs/for-ops/cli/diff","2eb"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/encrypt",component:p("/docs/for-ops/cli/encrypt","689"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/installation",component:p("/docs/for-ops/cli/installation","af1"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/known-issues",component:p("/docs/for-ops/cli/known-issues","548"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/lint",component:p("/docs/for-ops/cli/lint","770"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/pull",component:p("/docs/for-ops/cli/pull","83f"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/rotate-keys",component:p("/docs/for-ops/cli/rotate-keys","f9d"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/status",component:p("/docs/for-ops/cli/status","b45"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/sync",component:p("/docs/for-ops/cli/sync","e42"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/template",component:p("/docs/for-ops/cli/template","4e3"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/test",component:p("/docs/for-ops/cli/test","a8c"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/validate-templates",component:p("/docs/for-ops/cli/validate-templates","9a5"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/validate-values",component:p("/docs/for-ops/cli/validate-values","9ed"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/values",component:p("/docs/for-ops/cli/values","4af"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/cli/x",component:p("/docs/for-ops/cli/x","da3"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/apps",component:p("/docs/for-ops/console/apps","a5e"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/backups",component:p("/docs/for-ops/console/backups","795"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/builds",component:p("/docs/for-ops/console/builds","ec9"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/clusters",component:p("/docs/for-ops/console/clusters","655"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/deploy-changes",component:p("/docs/for-ops/console/deploy-changes","a49"),exact:!0},{path:"/docs/for-ops/console/overview",component:p("/docs/for-ops/console/overview","e4a"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/policies",component:p("/docs/for-ops/console/policies","c53"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/projects",component:p("/docs/for-ops/console/projects","75a"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/secrets",component:p("/docs/for-ops/console/secrets","791"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/services",component:p("/docs/for-ops/console/services","c27"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/alerts",component:p("/docs/for-ops/console/settings/alerts","ed2"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/azure",component:p("/docs/for-ops/console/settings/azure","87d"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/backup",component:p("/docs/for-ops/console/settings/backup","501"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/cluster",component:p("/docs/for-ops/console/settings/cluster","66d"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/co-monitoring",component:p("/docs/for-ops/console/settings/co-monitoring","d07"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/dns",component:p("/docs/for-ops/console/settings/dns","853"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/ingress",component:p("/docs/for-ops/console/settings/ingress","d6e"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/key-management",component:p("/docs/for-ops/console/settings/key-management","2a4"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/oidc",component:p("/docs/for-ops/console/settings/oidc","6e2"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/otomi",component:p("/docs/for-ops/console/settings/otomi","d98"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/settings/smtp",component:p("/docs/for-ops/console/settings/smtp","bcd"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/shell",component:p("/docs/for-ops/console/shell","40c"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/shortcuts",component:p("/docs/for-ops/console/shortcuts","45b"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/teams",component:p("/docs/for-ops/console/teams","a65"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/console/workloads",component:p("/docs/for-ops/console/workloads","d65"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/how-to/backups",component:p("/docs/for-ops/how-to/backups","7f1"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/how-to/core-only",component:p("/docs/for-ops/how-to/core-only","415"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/how-to/ingress-classes",component:p("/docs/for-ops/how-to/ingress-classes","0ae"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/how-to/install-with-dns",component:p("/docs/for-ops/how-to/install-with-dns","d06"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/how-to/switch-to-dns",component:p("/docs/for-ops/how-to/switch-to-dns","ce0"),exact:!0},{path:"/docs/for-ops/how-to/use-team-admin",component:p("/docs/for-ops/how-to/use-team-admin","fbd"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/sre/daily",component:p("/docs/for-ops/sre/daily","532"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/sre/overview",component:p("/docs/for-ops/sre/overview","461"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/sre/troubleshooting",component:p("/docs/for-ops/sre/troubleshooting","1f6"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/for-ops/sre/upgrades",component:p("/docs/for-ops/sre/upgrades","da0"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/get-started/activation",component:p("/docs/get-started/activation","efb"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/get-started/chart",component:p("/docs/get-started/chart","5cc"),exact:!0},{path:"/docs/get-started/installation",component:p("/docs/get-started/installation","a06"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/get-started/optional",component:p("/docs/get-started/optional","8c9"),exact:!0},{path:"/docs/get-started/prerequisites",component:p("/docs/get-started/prerequisites","858"),exact:!0,sidebar:"mainSidebar"},{path:"/docs/tutorials/overview",component:p("/docs/tutorials/overview","7fc"),exact:!0},{path:"/docs/tutorials/tutorial-1",component:p("/docs/tutorials/tutorial-1","075"),exact:!0},{path:"/docs/tutorials/tutorial-10",component:p("/docs/tutorials/tutorial-10","b8b"),exact:!0},{path:"/docs/tutorials/tutorial-2",component:p("/docs/tutorials/tutorial-2","720"),exact:!0},{path:"/docs/tutorials/tutorial-3",component:p("/docs/tutorials/tutorial-3","1c7"),exact:!0},{path:"/docs/tutorials/tutorial-4",component:p("/docs/tutorials/tutorial-4","10d"),exact:!0},{path:"/docs/tutorials/tutorial-5",component:p("/docs/tutorials/tutorial-5","4dc"),exact:!0},{path:"/docs/tutorials/tutorial-6",component:p("/docs/tutorials/tutorial-6","393"),exact:!0},{path:"/docs/tutorials/tutorial-7",component:p("/docs/tutorials/tutorial-7","028"),exact:!0},{path:"/docs/tutorials/tutorial-8",component:p("/docs/tutorials/tutorial-8","c9a"),exact:!0},{path:"/docs/tutorials/tutorial-9",component:p("/docs/tutorials/tutorial-9","e79"),exact:!0},{path:"/docs/tutorials/tutorials/create-k8s-service",component:p("/docs/tutorials/tutorials/create-k8s-service","d97"),exact:!0},{path:"/docs/tutorials/tutorials/create-knative-service",component:p("/docs/tutorials/tutorials/create-knative-service","0c7"),exact:!0},{path:"/docs/tutorials/tutorials/create-ksvc-otomi",component:p("/docs/tutorials/tutorials/create-ksvc-otomi","f7a"),exact:!0},{path:"/docs/tutorials/tutorials/use-secret",component:p("/docs/tutorials/tutorials/use-secret","125"),exact:!0}]},{path:"/product",component:p("/product","ebc"),routes:[{path:"/product/architecture",component:p("/product/architecture","754"),exact:!0,sidebar:"mainSidebar"},{path:"/product/eula/v1",component:p("/product/eula/v1","6c8"),exact:!0,sidebar:"mainSidebar"},{path:"/product/faq",component:p("/product/faq","401"),exact:!0,sidebar:"mainSidebar"},{path:"/product/introduction",component:p("/product/introduction","2ba"),exact:!0,sidebar:"mainSidebar"},{path:"/product/roadmap",component:p("/product/roadmap","94b"),exact:!0,sidebar:"mainSidebar"},{path:"/product/use-cases/adoption-framework",component:p("/product/use-cases/adoption-framework","0e7"),exact:!0,sidebar:"mainSidebar"},{path:"/product/use-cases/ci-cd",component:p("/product/use-cases/ci-cd","672"),exact:!0,sidebar:"mainSidebar"},{path:"/product/use-cases/edge",component:p("/product/use-cases/edge","f15"),exact:!0},{path:"/product/use-cases/multi-cluster",component:p("/product/use-cases/multi-cluster","a5e"),exact:!0},{path:"/product/use-cases/multi-tenancy",component:p("/product/use-cases/multi-tenancy","114"),exact:!0,sidebar:"mainSidebar"},{path:"/product/use-cases/overview",component:p("/product/use-cases/overview","819"),exact:!0,sidebar:"mainSidebar"},{path:"/product/use-cases/serverless",component:p("/product/use-cases/serverless","ec9"),exact:!0,sidebar:"mainSidebar"}]},{path:"/",component:p("/","050"),exact:!0},{path:"*",component:p("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>a});var r=n(7294);const o=r.createContext(!1);function a(e){let{children:t}=e;const[n,a]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{a(!0)}),[]),r.createElement(o.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),o=n(3935),a=n(3727),i=n(405),s=n(412);const l=[n(6657),n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6775),d=n(8790);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),h=n(2263),g=n(4996),b=n(6668),v=n(833),y=n(4711),w=n(9727),k=n(3320),S=n(197);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,h.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:o}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:o})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function x(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),o=function(){const{siteConfig:{url:e}}=(0,h.Z)(),{pathname:t}=(0,u.TH)();return e+(0,g.Z)(t)}(),a=t?`${n}${t}`:o;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:a}),r.createElement("link",{rel:"canonical",href:a}))}function _(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(x,null),r.createElement(E,null),r.createElement(S.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const T=new Map;function C(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var A=n(8934),L=n(8940);function R(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r(t.default?.[e]??t[e])?.(...n)));return()=>o.forEach((e=>e?.()))}const P=function(e){let{children:t,location:n,previousLocation:o}=e;return(0,r.useLayoutEffect)((()=>{o!==n&&(o&&function(e){const{hash:t}=e;if(t){const e=decodeURIComponent(t.substring(1));document.getElementById(e)?.scrollIntoView()}else window.scrollTo(0,0)}(n),R("onRouteDidUpdate",{previousLocation:o,location:n}))}),[o,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class N extends r.Component{constructor(e){super(e),this.previousLocation=void 0,this.routeUpdateCleanupCb=void 0,this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.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 r.createElement(P,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const I=N,D="docusaurus-base-url-issue-banner-container",M="docusaurus-base-url-issue-banner-suggestion-container",F="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${F}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${F}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[F]=!1}),[]),r.createElement(r.Fragment,null,!s.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:D}))}function z(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(j,null):null}function U(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:o,localeConfigs:a}}=(0,h.Z)(),i=(0,g.Z)(e),{htmlLang:s,direction:l}=a[o];return r.createElement(m.Z,null,r.createElement("html",{lang:s,dir:l}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var $=n(4763);function q(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement($.Z,null,r.createElement(L.M,null,r.createElement(A.t,null,r.createElement(p,null,r.createElement(U,null),r.createElement(_,null),r.createElement(z,null),r.createElement(I,{location:C(t)},e)))))}var G=n(6887);const H=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 r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();(document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode)?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Z=n(9670);const V=new Set,W=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Y={prefetch(e){if(!(e=>!K()&&!W.has(e)&&!V.has(e))(e))return!1;V.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Z.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?H(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!W.has(e))(e)&&(W.add(e),O(e))},Q=Object.freeze(Y);if(s.Z.canUseDOM){window.docusaurus=Q;const e=o.hydrate;O(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(a.VK,null,r.createElement(q,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),o=n(6809);const a=JSON.parse('{"docusaurus-plugin-google-gtag":{"default":{"trackingID":"G-KKV4ZVDEKQ","anonymizeIP":false,"id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"get-started/prerequisites","docs":[{"id":"apps/alertmanager","path":"/docs/apps/alertmanager","sidebar":"mainSidebar"},{"id":"apps/argocd","path":"/docs/apps/argocd","sidebar":"mainSidebar"},{"id":"apps/certmanager","path":"/docs/apps/certmanager","sidebar":"mainSidebar"},{"id":"apps/drone","path":"/docs/apps/drone","sidebar":"mainSidebar"},{"id":"apps/external-dns","path":"/docs/apps/external-dns","sidebar":"mainSidebar"},{"id":"apps/falco","path":"/docs/apps/falco"},{"id":"apps/gatekeeper","path":"/docs/apps/gatekeeper","sidebar":"mainSidebar"},{"id":"apps/gitea","path":"/docs/apps/gitea","sidebar":"mainSidebar"},{"id":"apps/grafana","path":"/docs/apps/grafana","sidebar":"mainSidebar"},{"id":"apps/harbor","path":"/docs/apps/harbor","sidebar":"mainSidebar"},{"id":"apps/ingress-nginx","path":"/docs/apps/ingress-nginx","sidebar":"mainSidebar"},{"id":"apps/istio","path":"/docs/apps/istio","sidebar":"mainSidebar"},{"id":"apps/jaeger","path":"/docs/apps/jaeger","sidebar":"mainSidebar"},{"id":"apps/keycloak","path":"/docs/apps/keycloak","sidebar":"mainSidebar"},{"id":"apps/kiali","path":"/docs/apps/kiali"},{"id":"apps/knative","path":"/docs/apps/knative","sidebar":"mainSidebar"},{"id":"apps/kubeapps","path":"/docs/apps/kubeapps","sidebar":"mainSidebar"},{"id":"apps/kubeclarity","path":"/docs/apps/kubeclarity","sidebar":"mainSidebar"},{"id":"apps/loki","path":"/docs/apps/loki","sidebar":"mainSidebar"},{"id":"apps/minio","path":"/docs/apps/minio","sidebar":"mainSidebar"},{"id":"apps/prometheus","path":"/docs/apps/prometheus","sidebar":"mainSidebar"},{"id":"apps/tekton","path":"/docs/apps/tekton","sidebar":"mainSidebar"},{"id":"apps/thanos","path":"/docs/apps/thanos","sidebar":"mainSidebar"},{"id":"apps/trivy","path":"/docs/apps/trivy","sidebar":"mainSidebar"},{"id":"apps/vault","path":"/docs/apps/vault","sidebar":"mainSidebar"},{"id":"apps/velero","path":"/docs/apps/velero","sidebar":"mainSidebar"},{"id":"for-ciso/overview","path":"/docs/for-ciso/overview"},{"id":"for-devs/console/apps","path":"/docs/for-devs/console/apps","sidebar":"mainSidebar"},{"id":"for-devs/console/builds","path":"/docs/for-devs/console/builds","sidebar":"mainSidebar"},{"id":"for-devs/console/deploy-changes","path":"/docs/for-devs/console/deploy-changes","sidebar":"mainSidebar"},{"id":"for-devs/console/projects","path":"/docs/for-devs/console/projects","sidebar":"mainSidebar"},{"id":"for-devs/console/secrets","path":"/docs/for-devs/console/secrets","sidebar":"mainSidebar"},{"id":"for-devs/console/services","path":"/docs/for-devs/console/services","sidebar":"mainSidebar"},{"id":"for-devs/console/settings","path":"/docs/for-devs/console/settings","sidebar":"mainSidebar"},{"id":"for-devs/console/shell","path":"/docs/for-devs/console/shell","sidebar":"mainSidebar"},{"id":"for-devs/console/shortcuts","path":"/docs/for-devs/console/shortcuts","sidebar":"mainSidebar"},{"id":"for-devs/console/workloads","path":"/docs/for-devs/console/workloads","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-1","path":"/docs/for-devs/get-started/lab-1","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-10","path":"/docs/for-devs/get-started/lab-10","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-11","path":"/docs/for-devs/get-started/lab-11","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-12","path":"/docs/for-devs/get-started/lab-12","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-13","path":"/docs/for-devs/get-started/lab-13","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-14","path":"/docs/for-devs/get-started/lab-14"},{"id":"for-devs/get-started/lab-15","path":"/docs/for-devs/get-started/lab-15","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-16","path":"/docs/for-devs/get-started/lab-16"},{"id":"for-devs/get-started/lab-17","path":"/docs/for-devs/get-started/lab-17","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-18","path":"/docs/for-devs/get-started/lab-18","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-19","path":"/docs/for-devs/get-started/lab-19","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-2","path":"/docs/for-devs/get-started/lab-2","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-20","path":"/docs/for-devs/get-started/lab-20","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-21","path":"/docs/for-devs/get-started/lab-21","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-22","path":"/docs/for-devs/get-started/lab-22","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-23","path":"/docs/for-devs/get-started/lab-23","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-24","path":"/docs/for-devs/get-started/lab-24","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-25","path":"/docs/for-devs/get-started/lab-25","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-3","path":"/docs/for-devs/get-started/lab-3","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-4","path":"/docs/for-devs/get-started/lab-4","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-5","path":"/docs/for-devs/get-started/lab-5","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-6","path":"/docs/for-devs/get-started/lab-6","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-7","path":"/docs/for-devs/get-started/lab-7","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-8","path":"/docs/for-devs/get-started/lab-8","sidebar":"mainSidebar"},{"id":"for-devs/get-started/lab-9","path":"/docs/for-devs/get-started/lab-9"},{"id":"for-devs/get-started/overview","path":"/docs/for-devs/get-started/overview","sidebar":"mainSidebar"},{"id":"for-ops/cli/apply","path":"/docs/for-ops/cli/apply","sidebar":"mainSidebar"},{"id":"for-ops/cli/bash","path":"/docs/for-ops/cli/bash","sidebar":"mainSidebar"},{"id":"for-ops/cli/bootstrap","path":"/docs/for-ops/cli/bootstrap","sidebar":"mainSidebar"},{"id":"for-ops/cli/check-policies","path":"/docs/for-ops/cli/check-policies","sidebar":"mainSidebar"},{"id":"for-ops/cli/commit","path":"/docs/for-ops/cli/commit","sidebar":"mainSidebar"},{"id":"for-ops/cli/decrypt","path":"/docs/for-ops/cli/decrypt","sidebar":"mainSidebar"},{"id":"for-ops/cli/deploying","path":"/docs/for-ops/cli/deploying","sidebar":"mainSidebar"},{"id":"for-ops/cli/destroy","path":"/docs/for-ops/cli/destroy","sidebar":"mainSidebar"},{"id":"for-ops/cli/diff","path":"/docs/for-ops/cli/diff","sidebar":"mainSidebar"},{"id":"for-ops/cli/encrypt","path":"/docs/for-ops/cli/encrypt","sidebar":"mainSidebar"},{"id":"for-ops/cli/installation","path":"/docs/for-ops/cli/installation","sidebar":"mainSidebar"},{"id":"for-ops/cli/known-issues","path":"/docs/for-ops/cli/known-issues","sidebar":"mainSidebar"},{"id":"for-ops/cli/lint","path":"/docs/for-ops/cli/lint","sidebar":"mainSidebar"},{"id":"for-ops/cli/pull","path":"/docs/for-ops/cli/pull","sidebar":"mainSidebar"},{"id":"for-ops/cli/rotate-keys","path":"/docs/for-ops/cli/rotate-keys","sidebar":"mainSidebar"},{"id":"for-ops/cli/status","path":"/docs/for-ops/cli/status","sidebar":"mainSidebar"},{"id":"for-ops/cli/sync","path":"/docs/for-ops/cli/sync","sidebar":"mainSidebar"},{"id":"for-ops/cli/template","path":"/docs/for-ops/cli/template","sidebar":"mainSidebar"},{"id":"for-ops/cli/test","path":"/docs/for-ops/cli/test","sidebar":"mainSidebar"},{"id":"for-ops/cli/validate-templates","path":"/docs/for-ops/cli/validate-templates","sidebar":"mainSidebar"},{"id":"for-ops/cli/validate-values","path":"/docs/for-ops/cli/validate-values","sidebar":"mainSidebar"},{"id":"for-ops/cli/values","path":"/docs/for-ops/cli/values","sidebar":"mainSidebar"},{"id":"for-ops/cli/x","path":"/docs/for-ops/cli/x","sidebar":"mainSidebar"},{"id":"for-ops/console/apps","path":"/docs/for-ops/console/apps","sidebar":"mainSidebar"},{"id":"for-ops/console/backups","path":"/docs/for-ops/console/backups","sidebar":"mainSidebar"},{"id":"for-ops/console/builds","path":"/docs/for-ops/console/builds","sidebar":"mainSidebar"},{"id":"for-ops/console/clusters","path":"/docs/for-ops/console/clusters","sidebar":"mainSidebar"},{"id":"for-ops/console/deploy-changes","path":"/docs/for-ops/console/deploy-changes"},{"id":"for-ops/console/overview","path":"/docs/for-ops/console/overview","sidebar":"mainSidebar"},{"id":"for-ops/console/policies","path":"/docs/for-ops/console/policies","sidebar":"mainSidebar"},{"id":"for-ops/console/projects","path":"/docs/for-ops/console/projects","sidebar":"mainSidebar"},{"id":"for-ops/console/secrets","path":"/docs/for-ops/console/secrets","sidebar":"mainSidebar"},{"id":"for-ops/console/services","path":"/docs/for-ops/console/services","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/alerts","path":"/docs/for-ops/console/settings/alerts","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/azure","path":"/docs/for-ops/console/settings/azure","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/backup","path":"/docs/for-ops/console/settings/backup","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/cluster","path":"/docs/for-ops/console/settings/cluster","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/co-monitoring","path":"/docs/for-ops/console/settings/co-monitoring","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/dns","path":"/docs/for-ops/console/settings/dns","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/ingress","path":"/docs/for-ops/console/settings/ingress","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/key-management","path":"/docs/for-ops/console/settings/key-management","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/oidc","path":"/docs/for-ops/console/settings/oidc","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/otomi","path":"/docs/for-ops/console/settings/otomi","sidebar":"mainSidebar"},{"id":"for-ops/console/settings/smtp","path":"/docs/for-ops/console/settings/smtp","sidebar":"mainSidebar"},{"id":"for-ops/console/shell","path":"/docs/for-ops/console/shell","sidebar":"mainSidebar"},{"id":"for-ops/console/shortcuts","path":"/docs/for-ops/console/shortcuts","sidebar":"mainSidebar"},{"id":"for-ops/console/teams","path":"/docs/for-ops/console/teams","sidebar":"mainSidebar"},{"id":"for-ops/console/workloads","path":"/docs/for-ops/console/workloads","sidebar":"mainSidebar"},{"id":"for-ops/how-to/core-only","path":"/docs/for-ops/how-to/core-only","sidebar":"mainSidebar"},{"id":"for-ops/how-to/create-and-restore-backups","path":"/docs/for-ops/how-to/backups","sidebar":"mainSidebar"},{"id":"for-ops/how-to/ingress-classes","path":"/docs/for-ops/how-to/ingress-classes","sidebar":"mainSidebar"},{"id":"for-ops/how-to/install-with-dns","path":"/docs/for-ops/how-to/install-with-dns","sidebar":"mainSidebar"},{"id":"for-ops/how-to/switch-to-dns","path":"/docs/for-ops/how-to/switch-to-dns"},{"id":"for-ops/how-to/use-team-admin","path":"/docs/for-ops/how-to/use-team-admin","sidebar":"mainSidebar"},{"id":"for-ops/sre/daily","path":"/docs/for-ops/sre/daily","sidebar":"mainSidebar"},{"id":"for-ops/sre/overview","path":"/docs/for-ops/sre/overview","sidebar":"mainSidebar"},{"id":"for-ops/sre/troubleshooting","path":"/docs/for-ops/sre/troubleshooting","sidebar":"mainSidebar"},{"id":"for-ops/sre/upgrades","path":"/docs/for-ops/sre/upgrades","sidebar":"mainSidebar"},{"id":"get-started/activation","path":"/docs/get-started/activation","sidebar":"mainSidebar"},{"id":"get-started/chart","path":"/docs/get-started/chart"},{"id":"get-started/installation","path":"/docs/get-started/installation","sidebar":"mainSidebar"},{"id":"get-started/optional","path":"/docs/get-started/optional"},{"id":"get-started/prerequisites","path":"/docs/get-started/prerequisites","sidebar":"mainSidebar"},{"id":"tutorials/overview","path":"/docs/tutorials/overview"},{"id":"tutorials/tutorial-1","path":"/docs/tutorials/tutorial-1"},{"id":"tutorials/tutorial-10","path":"/docs/tutorials/tutorial-10"},{"id":"tutorials/tutorial-2","path":"/docs/tutorials/tutorial-2"},{"id":"tutorials/tutorial-3","path":"/docs/tutorials/tutorial-3"},{"id":"tutorials/tutorial-4","path":"/docs/tutorials/tutorial-4"},{"id":"tutorials/tutorial-5","path":"/docs/tutorials/tutorial-5"},{"id":"tutorials/tutorial-6","path":"/docs/tutorials/tutorial-6"},{"id":"tutorials/tutorial-7","path":"/docs/tutorials/tutorial-7"},{"id":"tutorials/tutorial-8","path":"/docs/tutorials/tutorial-8"},{"id":"tutorials/tutorial-9","path":"/docs/tutorials/tutorial-9"},{"id":"tutorials/tutorial-create-byo-ksvc","path":"/docs/tutorials/tutorials/create-knative-service"},{"id":"tutorials/tutorial-create-byo-svc","path":"/docs/tutorials/tutorials/create-k8s-service"},{"id":"tutorials/tutorial-create-otomi-ksvc","path":"/docs/tutorials/tutorials/create-ksvc-otomi"},{"id":"tutorials/tutorial-use-secrets","path":"/docs/tutorials/tutorials/use-secret"}],"draftIds":[],"sidebars":{"mainSidebar":{"link":{"path":"/docs/get-started/prerequisites","label":"get-started/prerequisites"}}}}],"breadcrumbs":false},"product":{"path":"/product","versions":[{"name":"current","label":"Next","isLast":true,"path":"/product","mainDocId":"introduction","docs":[{"id":"architecture","path":"/product/architecture","sidebar":"mainSidebar"},{"id":"eula/v1","path":"/product/eula/v1","sidebar":"mainSidebar"},{"id":"faq","path":"/product/faq","sidebar":"mainSidebar"},{"id":"introduction","path":"/product/introduction","sidebar":"mainSidebar"},{"id":"roadmap","path":"/product/roadmap","sidebar":"mainSidebar"},{"id":"use-cases/adoption-framework","path":"/product/use-cases/adoption-framework","sidebar":"mainSidebar"},{"id":"use-cases/ci-cd","path":"/product/use-cases/ci-cd","sidebar":"mainSidebar"},{"id":"use-cases/edge","path":"/product/use-cases/edge"},{"id":"use-cases/multi-cluster","path":"/product/use-cases/multi-cluster"},{"id":"use-cases/multi-tenancy","path":"/product/use-cases/multi-tenancy","sidebar":"mainSidebar"},{"id":"use-cases/overview","path":"/product/use-cases/overview","sidebar":"mainSidebar"},{"id":"use-cases/serverless","path":"/product/use-cases/serverless","sidebar":"mainSidebar"}],"draftIds":[],"sidebars":{"mainSidebar":{"link":{"path":"/product/introduction","label":"introduction"}}}}],"breadcrumbs":false},"community":{"path":"/community","versions":[{"name":"current","label":"Next","isLast":true,"path":"/community","mainDocId":"welcome","docs":[{"id":"code-of-conduct","path":"/community/code-of-conduct","sidebar":"mainSidebar"},{"id":"expectations","path":"/community/expectations","sidebar":"mainSidebar"},{"id":"values","path":"/community/community-values","sidebar":"mainSidebar"},{"id":"welcome","path":"/community/welcome","sidebar":"mainSidebar"}],"draftIds":[],"sidebars":{"mainSidebar":{"link":{"path":"/community/welcome","label":"welcome"}}}}],"breadcrumbs":false}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"2.2.0","siteVersion":"0.15.3","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.2.0"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.2.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.2.0"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"2.2.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.2.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.2.0"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.2.0"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"2.2.0"}}}'),c={siteConfig:o.default,siteMetadata:l,globalData:a,i18n:i,codeTranslations:s},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7294),o=n(412),a=n(5742),i=n(9889);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",height:"50vh",width:"100%",fontSize:"20px"}},r.createElement("h1",null,"This page crashed."),r.createElement("p",null,t.message),r.createElement("button",{type:"button",onClick:n},"Try again"))}function l(e){let{error:t,tryAgain:n}=e;return r.createElement(u,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(a.Z,null,r.createElement("title",null,"Page Error")),r.createElement(i.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const c=e=>r.createElement(l,e);class u extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.Z.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??c)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(405);function a(e){return r.createElement(o.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7462),o=n(7294),a=n(3727),i=n(8780),s=n(2263),l=n(3919),c=n(412);const u=o.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":g,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,s.Z)(),{withBaseUrl:k}=(0,d.C)(),S=(0,o.useContext)(u),E=(0,o.useRef)(null);(0,o.useImperativeHandle)(t,(()=>E.current));const x=p||f;const _=(0,l.Z)(x),T=x?.replace("pathname://","");let C=void 0!==T?(A=T,b&&(e=>e.startsWith("/"))(A)?k(A):A):void 0;var A;C&&_&&(C=(0,i.applyTrailingSlash)(C,{trailingSlash:y,baseUrl:w}));const L=(0,o.useRef)(!1),R=n?a.OL:a.rU,P=c.Z.canUseIntersectionObserver,O=(0,o.useRef)(),N=()=>{L.current||null==C||(window.docusaurus.preload(C),L.current=!0)};(0,o.useEffect)((()=>(!P&&_&&null!=C&&window.docusaurus.prefetch(C),()=>{P&&O.current&&O.current.disconnect()})),[O,C,P,_]);const I=C?.startsWith("#")??!1,D=!C||!_||I;return D||g||S.collectLink(C),D?o.createElement("a",(0,r.Z)({ref:E,href:C},x&&!_&&{target:"_blank",rel:"noopener noreferrer"},v)):o.createElement(R,(0,r.Z)({},v,{onMouseEnter:N,onTouchStart:N,innerRef:e=>{E.current=e,P&&e&&_&&(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!=C&&window.docusaurus.prefetch(C))}))})),O.current.observe(e))},to:C},n&&{isActive:h,activeClassName:m}))}const f=o.forwardRef(p)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,I:()=>s});var r=n(7294);function o(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,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var a=n(7529);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 a[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return o(i({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:a}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const s=i({message:t,id:n});return r.createElement(r.Fragment,null,o(s,a))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>o,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>a,Z:()=>i});var r=n(2263),o=n(3919);function a(){const{siteConfig:{baseUrl:e,url:t}}=(0,r.Z)();return{withBaseUrl:(n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)}}function i(e,t){void 0===t&&(t={});const{withBaseUrl:n}=a();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8940);function a(){return(0,r.useContext)(o._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8934);function a(){return(0,r.useContext)(o._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});function r(e){const t={};return function e(n,r){Object.entries(n).forEach((n=>{let[o,a]=n;const i=r?`${r}.${o}`:o;var s;"object"==typeof(s=a)&&s&&Object.keys(s).length>0?e(a,i):t[i]=a}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>a});var r=n(7294);const o=r.createContext(null);function a(e){let{children:t,value:n}=e;const a=r.useContext(o),i=(0,r.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 r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:a,value:n})),[a,n]);return r.createElement(o.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>b,gA:()=>f,WS:()=>m,_r:()=>d,Jo:()=>v,zh:()=>p,yW:()=>g,gB:()=>h});var r=n(6775),o=n(2263),a=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=l(e,t),o=n?.docs.find((e=>!!(0,r.LX)(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((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,p=e=>function(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=i(e)?.[t];if(!r&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return r}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.TH)();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,r.LX)(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 m(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:l(t.pluginData,n)}}function h(e){return p(e).versions}function g(e){const t=p(e);return s(t)}function b(e){const t=p(e),{pathname:n}=(0,r.TH)();return c(t,n)}function v(e){const t=p(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},6657:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={onRouteDidUpdate(e){let{location:t,previousLocation:n}=e;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((()=>{window.gtag("event","page_view",{page_title:document.title,page_location:window.location.href,page_path:t.pathname+t.search+t.hash})}))}}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(4865),o=n.n(r);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()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),o=n(6809);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294);const o="iconExternalLink_nPIU";function a(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:o},r.createElement("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"}))}},9889:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Lt});var r=n(7294),o=n(6010),a=n(4763),i=n(7462),s=n(6775),l=n(5999),c=n(5936);const u="docusaurus_skipToContent_fallback";function d(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(u);t&&d(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&d(e.current)})),{containerRef:e,onClick:n}}const f=(0,l.I)({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 m(e){const t=e.children??f,{containerRef:n,onClick:o}=p();return r.createElement("div",{ref:n,role:"region","aria-label":f},r.createElement("a",(0,i.Z)({},e,{href:`#${u}`,onClick:o}),t))}var h=n(833),g=n(5281),b=n(9727);const v="skipToContent_fXgn";function y(){return r.createElement(m,{className:v})}var w=n(6668),k=n(9689);function S(e){let{width:t=21,height:n=21,color:o="currentColor",strokeWidth:a=1.2,className:s,...l}=e;return r.createElement("svg",(0,i.Z)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:o,strokeWidth:a},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const E="closeButton_CVFx";function x(e){return r.createElement("button",(0,i.Z)({type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,o.Z)("clean-btn close",E,e.className)}),r.createElement(S,{width:14,height:14,strokeWidth:3.1}))}const _="content_knG7";function T(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,i.Z)({},e,{className:(0,o.Z)(_,e.className),dangerouslySetInnerHTML:{__html:n}}))}const C="announcementBar_mb4j",A="announcementBarPlaceholder_vyr4",L="announcementBarClose_gvF7",R="announcementBarContent_xLdY";function P(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:o,textColor:a,isCloseable:i}=e;return r.createElement("div",{className:C,style:{backgroundColor:o,color:a},role:"banner"},i&&r.createElement("div",{className:A}),r.createElement(T,{className:R}),i&&r.createElement(x,{onClick:n,className:L}))}var O=n(2961),N=n(2466);var I=n(902),D=n(3102);const M=r.createContext(null);function F(e){let{children:t}=e;const n=function(){const e=(0,O.e)(),t=(0,D.HY)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,I.D9)(a);return(0,r.useEffect)((()=>{a&&!i&&o(!0)}),[a,i]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return r.createElement(M.Provider,{value:n},t)}function B(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function j(){const e=(0,r.useContext)(M);if(!e)throw new I.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,D.HY)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:B(a)})),[o,a,t])}function z(e){let{header:t,primaryMenu:n,secondaryMenu:a}=e;const{shown:i}=j();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,o.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},a)))}var U=n(2949),$=n(2389);function q(e){return r.createElement("svg",(0,i.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("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 G(e){return r.createElement("svg",(0,i.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("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 H={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:t,value:n,onChange:a}=e;const i=(0,$.Z)(),s=(0,l.I)({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"===n?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,o.Z)(H.toggle,t)},r.createElement("button",{className:(0,o.Z)("clean-btn",H.toggleButton,!i&&H.toggleButtonDisabled),type:"button",onClick:()=>a("dark"===n?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(q,{className:(0,o.Z)(H.toggleIcon,H.lightToggleIcon)}),r.createElement(G,{className:(0,o.Z)(H.toggleIcon,H.darkToggleIcon)})))}const V=r.memo(Z);function W(e){let{className:t}=e;const n=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,U.I)();return n?null:r.createElement(V,{className:t,value:o,onChange:a})}var K=n(1327);function Y(){return r.createElement(K.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Q(){const e=(0,O.e)();return r.createElement("button",{type:"button","aria-label":(0,l.I)({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()},r.createElement(S,{color:"var(--ifm-color-emphasis-600)"}))}function X(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(Y,null),r.createElement(W,{className:"margin-right--md"}),r.createElement(Q,null))}var J=n(9960),ee=n(4996),te=n(3919),ne=n(8022),re=n(9471);function oe(e){let{activeBasePath:t,activeBaseRegex:n,to:o,href:a,label:s,html:l,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const p=(0,ee.Z)(o),f=(0,ee.Z)(t),m=(0,ee.Z)(a,{forcePrependBaseUrl:!0}),h=s&&a&&!(0,te.Z)(a),g=l?{dangerouslySetInnerHTML:{__html:l}}:{children:r.createElement(r.Fragment,null,s,h&&r.createElement(re.Z,c&&{width:12,height:12}))};return a?r.createElement(J.Z,(0,i.Z)({href:u?m:a},d,g)):r.createElement(J.Z,(0,i.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?(0,ne.F)(n,t.pathname):t.pathname.startsWith(f)},d,g))}function ae(e){let{className:t,isDropdownItem:n=!1,...a}=e;const s=r.createElement(oe,(0,i.Z)({className:(0,o.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},a));return n?r.createElement("li",null,s):s}function ie(e){let{className:t,isDropdownItem:n,...a}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(oe,(0,i.Z)({className:(0,o.Z)("menu__link",t)},a)))}function se(e){let{mobile:t=!1,position:n,...o}=e;const a=t?ie:ae;return r.createElement(a,(0,i.Z)({},o,{activeClassName:o.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var le=n(6043),ce=n(8596),ue=n(2263);function de(e,t){return e.some((e=>function(e,t){return!!(0,ce.Mg)(e.to,t)||!!(0,ne.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function pe(e){let{items:t,position:n,className:a,onClick:s,...l}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}}),[c]),r.createElement("div",{ref:c,className:(0,o.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(oe,(0,i.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:l.to?void 0:"#",className:(0,o.Z)("navbar__link",a)},l,{onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),l.children??l.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,n)=>r.createElement(Ge,(0,i.Z)({isDropdownItem:!0,onKeyDown:e=>{if(n===t.length-1&&"Tab"===e.key){e.preventDefault(),d(!1);const t=c.current.nextElementSibling;if(t){(t instanceof HTMLAnchorElement?t:t.querySelector("a")).focus()}}},activeClassName:"dropdown__link--active"},e,{key:n}))))))}function fe(e){let{items:t,className:n,position:a,onClick:l,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,ue.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=de(t,u),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,le.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),r.createElement("li",{className:(0,o.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(oe,(0,i.Z)({role:"button",className:(0,o.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),f()}}),c.children??c.label),r.createElement(le.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(Ge,(0,i.Z)({mobile:!0,isDropdownItem:!0,onClick:l,activeClassName:"menu__link--active"},e,{key:t}))))))}function me(e){let{mobile:t=!1,...n}=e;const o=t?fe:pe;return r.createElement(o,n)}var he=n(4711);function ge(e){let{width:t=20,height:n=20,...o}=e;return r.createElement("svg",(0,i.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},o),r.createElement("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 be="iconLanguage_nlXk";var ve=n(3935),ye=n(5742),we=n(6177);function ke(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var Se=n(830),Ee=["translations"];function xe(){return xe=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Ae="Ctrl";var Le=r.forwardRef((function(e,t){var n=e.translations,o=void 0===n?{}:n,a=Ce(e,Ee),i=o.buttonText,s=void 0===i?"Search":i,l=o.buttonAriaLabel,c=void 0===l?"Search":l,u=_e((0,r.useState)(null),2),d=u[0],p=u[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Ae))}),[]),r.createElement("button",xe({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},a,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(Se.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===Ae?r.createElement(ke,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Re=n(3320);const Pe={button:{buttonText:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,l.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,l.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,l.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,l.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,l.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,l.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,l.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,l.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Oe=null;function Ne(e){let{hit:t,children:n}=e;return r.createElement(J.Z,{to:t.url},n)}function Ie(e){let{state:t,onClose:n}=e;const{generateSearchPageLink:o}=(0,we.O)();return r.createElement(J.Z,{to:o(t.query),onClick:n},r.createElement(l.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits}},"See all {count} results"))}function De(e){let{contextualSearch:t,externalUrlRegex:o,...a}=e;const{siteMetadata:l}=(0,ue.Z)(),c=function(){const{locale:e,tags:t}=(0,Re._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),u=a.searchParameters?.facetFilters??[],d=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(c,u):u,p={...a.searchParameters,facetFilters:d},{withBaseUrl:f}=(0,ee.C)(),m=(0,s.k6)(),h=(0,r.useRef)(null),g=(0,r.useRef)(null),[b,v]=(0,r.useState)(!1),[y,w]=(0,r.useState)(void 0),k=(0,r.useCallback)((()=>Oe?Promise.resolve():Promise.all([n.e(6780).then(n.bind(n,6780)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,6945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,8894))]).then((e=>{let[{DocSearchModal:t}]=e;Oe=t}))),[]),S=(0,r.useCallback)((()=>{k().then((()=>{h.current=document.createElement("div"),document.body.insertBefore(h.current,document.body.firstChild),v(!0)}))}),[k,v]),E=(0,r.useCallback)((()=>{v(!1),h.current?.remove()}),[v]),x=(0,r.useCallback)((e=>{k().then((()=>{v(!0),w(e.key)}))}),[k,v,w]),_=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ne.F)(o,t)?window.location.href=t:m.push(t)}}).current,T=(0,r.useRef)((e=>e.map((e=>{if((0,ne.F)(o,e.url))return e;const t=new URL(e.url);return{...e,url:f(`${t.pathname}${t.hash}`)}})))).current,C=(0,r.useMemo)((()=>e=>r.createElement(Ie,(0,i.Z)({},e,{onClose:E}))),[E]),A=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",l.docusaurusVersion),e)),[l.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,o=e.onClose,a=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){(27===e.keyCode&&t||"k"===e.key.toLowerCase()&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?o():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&a&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&a(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,o,a,i])}({isOpen:b,onOpen:S,onClose:E,onInput:x,searchButtonRef:g}),r.createElement(r.Fragment,null,r.createElement(ye.Z,null,r.createElement("link",{rel:"preconnect",href:`https://${a.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})),r.createElement(Le,{onTouchStart:k,onFocus:k,onMouseOver:k,onClick:S,ref:g,translations:Pe.button}),b&&Oe&&h.current&&(0,ve.createPortal)(r.createElement(Oe,(0,i.Z)({onClose:E,initialScrollY:window.scrollY,initialQuery:y,navigator:_,transformItems:T,hitComponent:Ne,transformSearchClient:A},a.searchPagePath&&{resultsFooterComponent:C},a,{searchParameters:p,placeholder:Pe.placeholder,translations:Pe.modal})),h.current))}function Me(){const{siteConfig:e}=(0,ue.Z)();return r.createElement(De,e.themeConfig.algolia)}const Fe="searchBox_ZlJk";function Be(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,o.Z)(n,Fe)},t)}var je=n(143),ze=n(2802);var Ue=n(373);const $e=e=>e.docs.find((t=>t.id===e.mainDocId));const qe={default:se,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:o,...a}=e;const{i18n:{currentLocale:c,locales:u,localeConfigs:d}}=(0,ue.Z)(),p=(0,he.l)(),{search:f,hash:m}=(0,s.TH)(),h=[...n,...u.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===c?t?"menu__link--active":"dropdown__link--active":""}})),...o],g=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[c].label;return r.createElement(me,(0,i.Z)({},a,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(ge,{className:be}),g),items:h}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(Be,{className:n},r.createElement(Me,null))},dropdown:me,html:function(e){let{value:t,className:n,mobile:a=!1,isDropdownItem:i=!1}=e;const s=i?"li":"div";return r.createElement(s,{className:(0,o.Z)({navbar__item:!a&&!i,"menu__list-item":a},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:o,...a}=e;const{activeDoc:s}=(0,je.Iw)(o),l=(0,ze.vY)(t,o);return null===l?null:r.createElement(se,(0,i.Z)({exact:!0},a,{isActive:()=>s?.path===l.path||!!s?.sidebar&&s.sidebar===l.sidebar,label:n??l.id,to:l.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:o,...a}=e;const{activeDoc:s}=(0,je.Iw)(o),l=(0,ze.oz)(t,o).link;if(!l)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(se,(0,i.Z)({exact:!0},a,{isActive:()=>s?.sidebar===t,label:n??l.label,to:l.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:o,...a}=e;const s=(0,ze.lO)(o)[0],l=t??s.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(s).path;return r.createElement(se,(0,i.Z)({},a,{label:l,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:o,dropdownItemsBefore:a,dropdownItemsAfter:c,...u}=e;const{search:d,hash:p}=(0,s.TH)(),f=(0,je.Iw)(n),m=(0,je.gB)(n),{savePreferredVersionName:h}=(0,Ue.J)(n),g=[...a,...m.map((e=>{const t=f.alternateDocVersions[e.name]??$e(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>h(e.name)}})),...c],b=(0,ze.lO)(n)[0],v=t&&g.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&g.length>1?void 0:$e(b).path;return g.length<=1?r.createElement(se,(0,i.Z)({},u,{mobile:t,label:v,to:y,isActive:o?()=>!1:void 0})):r.createElement(me,(0,i.Z)({},u,{mobile:t,label:v,to:y,items:g,isActive:o?()=>!1:void 0}))}};function Ge(e){let{type:t,...n}=e;const o=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=qe[o];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(a,n)}function He(){const e=(0,O.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(Ge,(0,i.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ze(e){return r.createElement("button",(0,i.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(l.Z,{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)"},"\u2190 Back to main menu"))}function Ve(){const e=0===(0,w.L)().navbar.items.length,t=j();return r.createElement(r.Fragment,null,!e&&r.createElement(Ze,{onClick:()=>t.hide()}),t.content)}function We(){const e=(0,O.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(z,{header:r.createElement(X,null),primaryMenu:r.createElement(He,null),secondaryMenu:r.createElement(Ve,null)}):null}const Ke="navbarHideable_m1mJ",Ye="navbarHidden_jGov";function Qe(e){return r.createElement("div",(0,i.Z)({role:"presentation"},e,{className:(0,o.Z)("navbar-sidebar__backdrop",e.className)}))}function Xe(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.L)(),i=(0,O.e)(),{navbarRef:s,isNavbarVisible:l}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,N.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:s,className:(0,o.Z)("navbar","navbar--fixed-top",n&&[Ke,!l&&Ye],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown})},t,r.createElement(Qe,{onClick:i.toggle}),r.createElement(We,null))}function Je(e){let{width:t=30,height:n=30,className:o,...a}=e;return r.createElement("svg",(0,i.Z)({className:o,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},a),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function et(){const{toggle:e,shown:t}=(0,O.e)();return r.createElement("button",{onClick:e,"aria-label":(0,l.I)({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"},r.createElement(Je,null))}const tt="colorModeToggle_DEke";function nt(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Ge,(0,i.Z)({},e,{key:t})))))}function rt(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function ot(){const e=(0,O.e)(),t=(0,w.L)().navbar.items,[n,o]=function(e){function t(e){return"left"===(e.position??"right")}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return r.createElement(rt,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(et,null),r.createElement(Y,null),r.createElement(nt,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(nt,{items:o}),r.createElement(W,{className:tt}),!a&&r.createElement(Be,null,r.createElement(Me,null)))})}function at(){return r.createElement(Xe,null,r.createElement(ot,null))}function it(e){let{item:t}=e;const{to:n,href:o,label:a,prependBaseUrlToHref:s,...l}=t,c=(0,ee.Z)(n),u=(0,ee.Z)(o,{forcePrependBaseUrl:!0});return r.createElement(J.Z,(0,i.Z)({className:"footer__link-item"},o?{href:s?u:o}:{to:c},l),a,o&&!(0,te.Z)(o)&&r.createElement(re.Z,null))}function st(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(it,{item:t}))}function lt(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(st,{key:t,item:e})))))}function ct(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(lt,{key:t,column:e}))))}function ut(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function dt(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(it,{item:t})}function pt(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(dt,{item:e}),t.length!==n+1&&r.createElement(ut,null))))))}function ft(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(ct,{columns:t}):r.createElement(pt,{links:t})}var mt=n(941);const ht="footerLogoLink_BH7S";function gt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,ee.C)(),a={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(mt.Z,{className:(0,o.Z)("footer__logo",t.className),alt:t.alt,sources:a,width:t.width,height:t.height,style:t.style})}function bt(e){let{logo:t}=e;return t.href?r.createElement(J.Z,{href:t.href,className:ht,target:t.target},r.createElement(gt,{logo:t})):r.createElement(gt,{logo:t})}function vt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function yt(e){let{style:t,links:n,logo:a,copyright:i}=e;return r.createElement("footer",{className:(0,o.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(a||i)&&r.createElement("div",{className:"footer__bottom text--center"},a&&r.createElement("div",{className:"margin-bottom--sm"},a),i)))}function wt(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:o,style:a}=e;return r.createElement(yt,{style:a,links:n&&n.length>0&&r.createElement(ft,{links:n}),logo:o&&r.createElement(bt,{logo:o}),copyright:t&&r.createElement(vt,{copyright:t})})}const kt=r.memo(wt);var St=n(12);const Et="docusaurus.tab.",xt=r.createContext(void 0);const _t=(0,I.Qc)([U.S,k.pl,function(e){let{children:t}=e;const n=function(){const[e,t]=(0,r.useState)({}),n=(0,r.useCallback)(((e,t)=>{(0,St.W)(`docusaurus.tab.${e}`).set(t)}),[]);(0,r.useEffect)((()=>{try{const e={};(0,St._)().forEach((t=>{if(t.startsWith(Et)){const n=t.substring(Et.length);e[n]=(0,St.W)(t).get()}})),t(e)}catch(e){console.error(e)}}),[]);const o=(0,r.useCallback)(((e,r)=>{t((t=>({...t,[e]:r}))),n(e,r)}),[n]);return(0,r.useMemo)((()=>({tabGroupChoices:e,setTabGroupChoices:o})),[e,o])}();return r.createElement(xt.Provider,{value:n},t)},N.OC,Ue.L5,h.VC,function(e){let{children:t}=e;return r.createElement(D.n2,null,r.createElement(O.M,null,r.createElement(F,null,t)))}]);function Tt(e){let{children:t}=e;return r.createElement(_t,null,t)}function Ct(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},r.createElement(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again when the page crashed"},"Try again"))))))}const At="mainWrapper_z2l0";function Lt(e){const{children:t,noFooter:n,wrapperClassName:i,title:s,description:l}=e;return(0,b.t)(),r.createElement(Tt,null,r.createElement(h.d,{title:s,description:l}),r.createElement(y,null),r.createElement(P,null),r.createElement(at,null),r.createElement("div",{id:u,className:(0,o.Z)(g.k.wrapper.main,At,i)},r.createElement(a.Z,{fallback:e=>r.createElement(Ct,e)},t)),!n&&r.createElement(kt,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),o=n(7294),a=n(9960),i=n(4996),s=n(2263),l=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},s=o.createElement(c.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?o.createElement("div",{className:r},s):s}function d(e){const{siteConfig:{title:t}}=(0,s.Z)(),{navbar:{title:n,logo:c}}=(0,l.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.Z)(c?.href||"/"),h=n?"":t,g=c?.alt??h;return o.createElement(a.Z,(0,r.Z)({to:m},f,c?.target&&{target:c.target}),c&&o.createElement(u,{logo:c,alt:g,imageClassName:d}),null!=n&&o.createElement("b",{className:p},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(5742);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return r.createElement(o.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),a&&r.createElement("meta",{name:"docusaurus_tag",content:a}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),a&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:a}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),o=n(7294),a=n(6010),i=n(2389),s=n(2949);const l={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,s.I)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return o.createElement(o.Fragment,null,f.map((e=>o.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,a.Z)(l.themedImage,l[`themedImage--${e}`],u)},p)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>i,z:()=>m});var r=n(7462),o=n(7294),a=n(412);function i(e){let{initialState:t}=e;const[n,r]=(0,o.useState)(t??!1),a=(0,o.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:a}}const s={display:"none",overflow:"hidden",height:"0px"},l={display:"block",overflow:"visible",height:"auto"};function c(e,t){const n=t?s:l;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function u(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const a=(0,o.useRef)(!1);(0,o.useEffect)((()=>{const e=t.current;function o(){const t=e.scrollHeight,n=r?.duration??function(e){const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??"ease-in-out"}`,height:`${t}px`}}function i(){const t=o();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return c(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=s.height,e.style.overflow=s.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function d(e){if(!a.Z.canUseDOM)return e?s:l}function p(e){let{as:t="div",collapsed:n,children:r,animation:a,onCollapseTransitionEnd:i,className:s,disableSSRStyle:l}=e;const p=(0,o.useRef)(null);return u({collapsibleRef:p,collapsed:n,animation:a}),o.createElement(t,{ref:p,style:l?void 0:d(n),onTransitionEnd:e=>{"height"===e.propertyName&&(c(p.current,n),i?.(n))},className:s},r)}function f(e){let{collapsed:t,...n}=e;const[a,i]=(0,o.useState)(!t),[s,l]=(0,o.useState)(t);return(0,o.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,o.useLayoutEffect)((()=>{a&&l(t)}),[a,t]),a?o.createElement(p,(0,r.Z)({},n,{collapsed:s})):null}function m(e){let{lazy:t,...n}=e;const r=t?f:p;return o.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(7294),o=n(2389),a=n(12),i=n(902),s=n(6668);const l=(0,a.W)("docusaurus.announcement.dismiss"),c=(0,a.W)("docusaurus.announcement.id"),u=()=>"true"===l.get(),d=e=>l.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,o.Z)(),[n,a]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{a(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>h});var r=n(7294),o=n(412),a=n(902),i=n(12),s=n(6668);const l=r.createContext(void 0),c="theme",u=(0,i.W)(c),d="light",p="dark",f=e=>e===p?p:d;function m(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,i]=(0,r.useState)((e=>o.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e))(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const l=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(i(t),o&&(e=>{u.set(f(e))})(t)):(i(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p:d:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&l(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,l]);const m=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||m.current?m.current=window.matchMedia("print").matches:l(null)};return e.addListener(r),()=>e.removeListener(r)}),[l,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:l,get isDarkTheme(){return a===p},setLightTheme(){l(d)},setDarkTheme(){l(p)}})),[a,l])}function h(e){let{children:t}=e;const n=m();return r.createElement(l.Provider,{value:n},t)}function g(){const e=(0,r.useContext)(l);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>y,L5:()=>b,Oh:()=>w});var r=n(7294),o=n(143),a=n(9935),i=n(6668),s=n(2802),l=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d=(e,t,n)=>{(0,c.W)(u(e),{persistence:t}).set(n)},p=(e,t)=>(0,c.W)(u(e),{persistence:t}).get(),f=(e,t)=>{(0,c.W)(u(e),{persistence:t}).del()};const m=r.createContext(null);function h(){const e=(0,o._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,s]=(0,r.useState)((()=>(e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}]))))(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(f(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,r.useMemo)((()=>({savePreferredVersion:function(e,n){d(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=h();return r.createElement(m.Provider,{value:n},t)}function b(e){let{children:t}=e;return s.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function v(){const e=(0,r.useContext)(m);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=a.m);const t=(0,o.zh)(e),[n,i]=v(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function w(){const e=(0,o._r)(),[t]=v();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,b:()=>s});var r=n(7294),o=n(902);const a=Symbol("EmptyContext"),i=r.createContext(a);function s(e){let{children:t,name:n,items:o}=e;const a=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return r.createElement(i.Provider,{value:a},t)}function l(){const e=(0,r.useContext)(i);if(e===a)throw new o.i6("DocsSidebarProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),o=n(3102),a=n(7524),i=n(6775),s=n(902);function l(e){!function(e){const t=(0,i.k6)(),n=(0,s.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[i,s]=(0,r.useState)(!1);l((()=>{if(i)return s(!1),!1}));const u=(0,r.useCallback)((()=>{s((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&s(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function p(e){let{children:t}=e;const n=d();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>l,n2:()=>i});var r=n(7294),o=n(902);const a=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(a.Provider,{value:n},t)}function s(){const e=(0,r.useContext)(a);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const i=(0,r.useContext)(a);if(!i)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,s]=i,l=(0,o.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>a});var r=n(7294);const o="navigation-with-keyboard";function a(){(0,r.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)}}),[])}},6177:(e,t,n)=>{"use strict";n.d(t,{O:()=>s});var r=n(7294),o=n(6775),a=n(2263);const i="q";function s(){const e=(0,o.k6)(),{siteConfig:{baseUrl:t}}=(0,a.Z)(),[n,s]=(0,r.useState)("");(0,r.useEffect)((()=>{const e=new URLSearchParams(window.location.search).get(i)??"";s(e)}),[]);return{searchQuery:n,setSearchQuery:(0,r.useCallback)((t=>{const n=new URLSearchParams(window.location.search);t?n.set(i,t):n.delete(i),e.replace({search:n.toString()}),s(t)}),[e]),generateSearchPageLink:(0,r.useCallback)((e=>`${t}search?q=${encodeURIComponent(e)}`),[t])}}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),o=n(412);const a="desktop",i="mobile",s="ssr";function l(){return o.Z.canUseDOM?window.innerWidth>996?a:i:s}function c(){const[e,t]=(0,r.useState)((()=>l()));return(0,r.useEffect)((()=>{function e(){t(l())}return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-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",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:{}}},2802:(e,t,n)=>{"use strict";n.d(t,{Wl:()=>p,_F:()=>m,cE:()=>d,hI:()=>w,lO:()=>b,vY:()=>y,oz:()=>v,s1:()=>g});var r=n(7294),o=n(6775),a=n(8790),i=n(143),s=n(373),l=n(1116);function c(e){return Array.from(new Set(e))}var u=n(8596);const d=!!i._r;function p(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=p(t);if(e)return e}}}const f=(e,t)=>void 0!==e&&(0,u.Mg)(e,t);function m(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||((e,t)=>e.some((e=>m(e,t))))(e.items,t))}function h(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,u.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,u.Mg)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function g(){const e=(0,l.V)(),{pathname:t}=(0,o.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?h({sidebarItems:e.items,pathname:t}):null}function b(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),o=(0,i.yW)(e);return(0,r.useMemo)((()=>c([t,n,o].filter(Boolean))),[t,n,o])}function v(e,t){const n=b(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\n Available sidebar ids are:\n - ${Object.keys(t).join("\n- ")}`);return r[1]}),[e,n])}function y(e,t){const n=b(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`DocNavbarItem: 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- ${c(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function w(e){let{route:t,versionMetadata:n}=e;const r=(0,o.TH)(),i=t.routes,s=i.find((e=>(0,o.LX)(r.pathname,e)));if(!s)return null;const l=s.sidebar,c=l?n.docsSidebars[l]:void 0;return{docElement:(0,a.H)(i),sidebarName:l,sidebarItems:c}}},2128:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(2263);function o(e){const{siteConfig:t}=(0,r.Z)(),{title:n,titleDelimiter:o}=t;return e?.trim().length?`${e.trim()} ${o} ${n}`:n}},833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(7294),o=n(6010),a=n(5742),i=n(226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),c=n(2128);function u(e){let{title:t,description:n,keywords:o,image:i,children:s}=e;const u=(0,c.p)(t),{withBaseUrl:d}=(0,l.C)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),o&&r.createElement("meta",{name:"keywords",content:Array.isArray(o)?o.join(","):o}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),s)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),s=(0,o.Z)(i,t);return r.createElement(d.Provider,{value:s},r.createElement(a.Z,null,r.createElement("html",{className:s})),n)}function f(e){let{children:t}=e;const n=s(),a=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,o.Z)(a,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>l,i6:()=>s,zX:()=>a});var r=n(7294);const o=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function a(e){const t=(0,r.useRef)(e);return o((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return o((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(7294),o=n(723),a=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,a.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(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(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>l,RF:()=>d});var r=n(7294),o=n(412),a=n(2389),i=n(902);const s=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(s.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(s);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),o=(0,r.useRef)(u()),a=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();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 p(){const e=(0,r.useRef)(null),t=(0,a.Z)()&&"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 r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&ot&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>l,os:()=>s});var r=n(143),o=n(2263),a=n(373);const i="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,o.Z)(),t=(0,r._r)(),n=(0,r.WS)(),l=(0,a.Oh)();const c=[i,...Object.keys(t).map((function(e){const r=n?.activePlugin.pluginId===e?n.activeVersion:void 0,o=l[e],a=t[e].versions.find((e=>e.isLast));return s(e,(r??o??a).name)}))];return{locale:e.currentLocale,tags:c}}},12:(e,t,n)=>{"use strict";n.d(t,{W:()=>s,_:()=>l});const r="localStorage";function o(e){if(void 0===e&&(e=r),"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,a||(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),a=!0),null}var t}let a=!1;const i={get:()=>null,set:()=>{},del:()=>{}};function s(e,t){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}}(e);const n=o(t?.persistence);return null===n?i:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{n.setItem(e,t)}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{n.removeItem(e)}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}}}}function l(e){void 0===e&&(e=r);const t=o(e);if(!t)return[];const n=[];for(let r=0;r{"use strict";n.d(t,{l:()=>a});var r=n(2263),o=n(6775);function a(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:a}}=(0,r.Z)(),{pathname:i}=(0,o.TH)(),s=a===n?e:e.replace(`/${a}/`,"/"),l=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:o}=e;return`${o?t:""}${function(e){return e===n?`${s}`:`${s}${e}/`}(r)}${l}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),o=n(6775),a=n(902);function i(e){const t=(0,o.TH)(),n=(0,a.D9)(t),i=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(2263);function o(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[o]=e.split(/[#?]/),a="/"===o||o===r?o:(i=o,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(o,a)}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="post-content";var o=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}})},6010:(e,t,n)=>{"use strict";function r(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;to});const o=function(){for(var e,t,n=0,o="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>T,ob:()=>f,PP:()=>A,Ep:()=>p});var r=n(7462);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r=0;p--){var f=i[p];"."===f?a(i,p):".."===f?(a(i,p),d++):d&&(a(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var s=n(2177);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(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 d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=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:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},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(s){throw s instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,h(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(1296),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},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||o}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=f(n);o&&o!==m&&e(t,o,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),h=l(n),g=0;g{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,s=n?Symbol.for("react.profiler"):60114,l=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,h=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function k(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case a:case s:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case g:case h:case l:return e;default:return t}}case o:return t}}}function S(e){return k(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=l,t.Element=r,t.ForwardRef=p,t.Fragment=a,t.Lazy=g,t.Memo=h,t.Portal=o,t.Profiler=s,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return S(e)||k(e)===u},t.isConcurrentMode=S,t.isContextConsumer=function(e){return k(e)===c},t.isContextProvider=function(e){return k(e)===l},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return k(e)===p},t.isFragment=function(e){return k(e)===a},t.isLazy=function(e){return k(e)===g},t.isMemo=function(e){return k(e)===h},t.isPortal=function(e){return k(e)===o},t.isProfiler=function(e){return k(e)===s},t.isStrictMode=function(e){return k(e)===i},t.isSuspense=function(e){return k(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===d||e===s||e===i||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===h||e.$$typeof===l||e.$$typeof===c||e.$$typeof===p||e.$$typeof===v||e.$$typeof===y||e.$$typeof===w||e.$$typeof===b)},t.typeOf=k},1296:(e,t,n)=>{"use strict";e.exports=n(6103)},1143:e=>{"use strict";e.exports=function(e,t,n,r,o,a,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,a,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=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:'
'};function o(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.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)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),c=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){l(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())}),r.trickleSpeed)};return r.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()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.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=r.template;var o,i=t.querySelector(r.barSelector),s=e?"-100":a(n.status||0),c=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(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 s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=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 r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(o){return!1}}()?Object.assign:function(e,a){for(var i,s,l=o(e),c=1;c{var r=n(5826);e.exports=f,e.exports.parse=a,e.exports.compile=function(e,t){return s(a(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,s="",u=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(i,f),i=f+d.length,p)s+=p[1];else{var m=e[i],h=n[2],g=n[3],b=n[4],v=n[5],y=n[6],w=n[7];s&&(r.push(s),s="");var k=null!=h&&null!=m&&m!==h,S="+"===y||"*"===y,E="?"===y||"*"===y,x=n[2]||u,_=b||v;r.push({name:g||a++,prefix:h||"",delimiter:x,optional:E,repeat:S,partial:k,asterisk:!!w,pattern:_?c(_):w?".*":"[^"+l(x)+"]+?"})}}return i{"use strict";n.d(t,{Z:()=>a});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={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(/=d.reach);E+=S.value.length,S=S.next){var x=S.value;if(t.length>e.length)return;if(!(x instanceof o)){var _,T=1;if(v){if(!(_=a(k,E,e,b))||_.index>=e.length)break;var C=_.index,A=_.index+_[0].length,L=E;for(L+=S.value.length;C>=L;)L+=(S=S.next).value.length;if(E=L-=S.value.length,S.value instanceof o)continue;for(var R=S;R!==t.tail&&(Ld.reach&&(d.reach=I);var D=S.prev;if(O&&(D=l(t,D,O),E+=O.length),c(t,D,T),S=l(t,D,new o(p,g?r.tokenize(P,g):P,y,P)),N&&l(t,S,N),T>1){var M={cause:p+","+m,reach:I};i(e,t,n,S.prev,E,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function s(){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 l(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function c(e,t,n){for(var r=t.next,o=0;o"+a.content+""},r}(),o=r;r.default=r,o.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\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://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"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},o.languages.markup.tag.inside["attr-value"].inside.entity=o.languages.markup.entity,o.languages.markup.doctype.inside["internal-subset"].inside=o.languages.markup,o.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(o.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:o.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:o.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},o.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(o.languages.markup.tag,"addAttribute",{value:function(e,t){o.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:o.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),o.languages.html=o.languages.markup,o.languages.mathml=o.languages.markup,o.languages.svg=o.languages.markup,o.languages.xml=o.languages.extend("markup",{}),o.languages.ssml=o.languages.xml,o.languages.atom=o.languages.xml,o.languages.rss=o.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var o=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],a=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},o.languages.c=o.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|[?:~]|[-+*/%&|^!=<>]=?/}),o.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),o.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},o.languages.c.string],char:o.languages.c.char,comment:o.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:o.languages.c}}}}),o.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 o.languages.c.boolean,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(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//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+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//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"])}(o),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,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;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(o),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;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("\\[(?:[^[\\]\"']|"+n.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":[n,{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}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},o={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|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:r,number:o,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:o})}(o),o.languages.javascript=o.languages.extend("clike",{"class-name":[o.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}|\?\?=?|\?\.?|[~:]/}),o.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,o.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:o.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:o.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:o.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:o.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:o.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),o.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:o.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"}}),o.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),o.languages.markup&&(o.languages.markup.tag.addInlined("script","javascript"),o.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")),o.languages.js=o.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],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"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(o),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\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:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(a),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?: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}(o),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;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(r),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(r),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__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\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(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.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,r=t.length;n",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(o),o.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:o.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+/},o.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;n0)){var s=p(/^\{$/,/^\}$/);if(-1===s)continue;for(var l=n;l=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\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,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],a=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function l(t,n,r){var o={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",o),o.tokens=e.tokenize(o.code,o.grammar),e.hooks.run("after-tokenize",o),o.tokens}function c(t){var n={};n["interpolation-punctuation"]=o;var a=e.tokenize(t,n);if(3===a.length){var i=[1,1];i.push.apply(i,l(a[1],e.languages.javascript,"javascript")),a.splice.apply(a,i)}return new e.Token("interpolation",a,r.alias,t)}function u(t,n,r){var o=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),i=0,u={},d=l(o.map((function(e){if("string"==typeof e)return e;for(var n,o=e.content;-1!==t.indexOf(n=s(i++,r)););return u[n]=o,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var o=p[i],a="string"==typeof r?r:r.content,s=a.indexOf(o);if(-1!==s){++i;var l=a.substring(0,s),d=c(u[o]),f=a.substring(s+o.length),m=[];if(l&&m.push(l),m.push(d),f){var h=[f];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,o=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,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}(o),function(e){function t(e,t){return RegExp(e.replace(//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*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\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*)#?/.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"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function a(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return o})),RegExp(e,t)}o=a(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\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(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=/.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(""):""},s=function(t){for(var n=[],r=0;r0&&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}):n.length>0&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof o)&&n.length>0&&0===n[n.length-1].openedBraces){var l=i(o);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(l=i(t[r-1])+l,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",l,null,l)}o.content&&"string"!=typeof o.content&&s(o.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(o),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],o=[];/^\w+$/.test(n)||o.push(/\w+/.exec(n)[0]),"diff"===n&&o.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:o,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(o),o.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},o.languages.go=o.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/}),o.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete o.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,s=i.length;-1!==n.code.indexOf(o=t(r,s));)++s;return i[s]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=a.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=a[o],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++o;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),v=[];h&&v.push.apply(v,i([h])),v.push(g),b&&v.push.apply(v,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(o),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(o),o.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},o.languages.webmanifest=o.languages.json,o.languages.less=o.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),o.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),o.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},o.languages.objectivec=o.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 o.languages.objectivec["class-name"],o.languages.objc=o.languages.objectivec,o.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},o.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:/[{}[\];(),.:]/},o.languages.python["string-interpolation"].inside.interpolation.inside.rest=o.languages.python,o.languages.py=o.languages.python,o.languages.reason=o.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/}),o.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 o.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(o),o.languages.scss=o.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),o.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),o.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),o.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),o.languages.scss.atrule.inside.rest=o.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?: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|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)\b/i,{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,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(o),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(o),o.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const a=o},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),o=n(9642),a=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),a.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6726},6500:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var s={},l=e[r];if(l){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in s))for(var i in o(t,a),s[t]=!0,n[t])s[i]=!0}t(l.require,c),t(l.optional,c),t(l.modify,c)}n[r]=s,a.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(a,i,s){var l=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var a=r[o];t[o]="string"==typeof a?{title:a}:a}}return t}(a),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var a=e[o];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(l);i=i.map(c),s=(s||[]).map(c);var u=n(i),d=n(s);i.forEach((function e(n){var r=l[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(l),m=u;o(m);){for(var h in p={},m){var g=l[h];t(g&&g.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var v in f(b))if(v in u){p[b]=!0;break}for(var y in m=p)u[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var a=o?o.series:void 0,i=o?o.parallel:e,s={},l={};function c(e){if(e in s)return s[e];l[e]=!0;var o,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)o=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete l[e],t})));a?o=a(p,(function(){return r(e)})):r(e)}return s[e]=o}for(var u in n)c(u);var d=[];for(var p in l)d.push(s[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var s=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 s.name="Invariant Violation",s}}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}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),o=n(7418),a=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n