PageSourceSearch

https://docs-spectrocloud.netlify.app/assets/js/a70a38b8.f61fb9b5.js

js docs-spectrocloud.netlify.app collected 2026-10-03 10:41:39 UTC 42,025 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkspectro_cloud_docs=self.webpackChunkspectro_cloud_docs||[]).push([["12742"],{700397:function(e,s,n){n.r(s),n.d(s,{frontMatter:()=>a,toc:()=>l,default:()=>h,metadata:()=>r,assets:()=>d,contentTitle:()=>c});var r=JSON.parse('{"id":"registries-and-packs/pack-constraints","title":"Pack Constraints","description":"Description of pack constraints and their usages within Spectro Cloud","source":"@site/docs/docs-content/registries-and-packs/pack-constraints.md","sourceDirName":"registries-and-packs","slug":"/registries-and-packs/pack-constraints","permalink":"/registries-and-packs/pack-constraints","draft":false,"unlisted":false,"editUrl":"https://github.com/spectrocloud/librarium/blob/master/docs/docs-content/registries-and-packs/pack-constraints.md","tags":[],"version":"current","lastUpdatedAt":1777826507000,"sidebarPosition":50,"frontMatter":{"sidebar_label":"Pack Constraints","title":"Pack Constraints","description":"Description of pack constraints and their usages within Spectro Cloud","icon":"","hide_table_of_contents":false,"sidebar_position":50},"sidebar":"docSidebar","previous":{"title":"Add an Add-on Pack","permalink":"/registries-and-packs/adding-add-on-packs"},"next":{"title":"Registries","permalink":"/registries-and-packs/registries/"}}'),t=n(474848),i=n(884429);let a={sidebar_label:"Pack Constraints",title:"Pack Constraints",description:"Description of pack constraints and their usages within Spectro Cloud",icon:"",hide_table_of_contents:!1,sidebar_position:50},c,d={},l=[{value:"Pack Values Constraints",id:"pack-values-constraints",level:2},{value:"Schema Constraints",id:"schema-constraints",level:2},{value:"Pack Dependency Constraints",id:"pack-dependency-constraints",level:2},{value:"Pack metadata JSON",id:"pack-metadata-json",level:2},{value:"Pack Dependency Attributes",id:"pack-dependency-attributes",level:2},{value:"Layer Types",id:"layer-types",level:4},{value:"Dependency Types",id:"dependency-types",level:4},{value:"Pack Resource Constraints",id:"pack-resource-constraints",level:2},{value:"Pack metadata JSON",id:"pack-metadata-json-1",level:2},{value:"Pack Resources Attributes",id:"pack-resources-attributes",level:2},{value:"Pack Presets",id:"pack-presets",level:2},{value:"Presets Metadata YAML",id:"presets-metadata-yaml",level:2},{value:"Preset Attributes",id:"preset-attributes",level:2},{value:"Pack Macros",id:"pack-macros",level:2},{value:"Types of Macros",id:"types-of-macros",level:2},{value:"Supported Variables",id:"supported-variables",level:3},{value:"Additional Capabilities",id:"additional-capabilities",level:2},{value:"Sprig Template Functions",id:"sprig-template-functions",level:3},{value:"How to set the default value?",id:"how-to-set-the-default-value",level:3}];function o(e){let s={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components},{TabItem:n,Tabs:r,VersionedLink:a}=s;return n||p("TabItem",!0),r||p("Tabs",!0),a||p("VersionedLink",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(s.p,{children:["Pack constraints are a set of rules defined at the pack level to validate the packs for a Profile or a Cluster ",(0,t.jsx)(s.em,{children:"before"}),"\nit gets created or updated. Packs must be validated before the cluster is submitted to ensure a successful deployment."]}),"\n",(0,t.jsx)("br",{}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsxs)(s.p,{children:["You can find information about the JSON schema for the pack metadata file in the\n",(0,t.jsx)(s.a,{href:"/registries-and-packs/add-custom-packs#json-schema",children:"JSON schema"})," section of the documentation."]})}),"\n",(0,t.jsx)(s.h2,{id:"pack-values-constraints",children:"Pack Values Constraints"}),"\n",(0,t.jsxs)(s.p,{children:["A Spectro Pack currently supports various configurations through a configuration file called ",(0,t.jsx)(s.code,{children:"values.yaml"}),". The values\ndefined in the config file are applied while deploying the Kubernetes cluster. The values defined in the pack are\ndefault values and can be overridden in the Cluster Profile or during the Cluster deployment."]}),"\n",(0,t.jsx)(s.p,{children:"Since the default pack values can be overridden, users may inadvertently set incorrect values leading to cluster\ndeployment failure. These failures can occur at any point during the cluster deployment process. If the system is\ncapable of detecting invalid pack values before the cluster is submitted for deployment, then deployment failures can be\novercome to some extent."}),"\n",(0,t.jsxs)(s.p,{children:["Pack value constraints are additional information provided through a template file called ",(0,t.jsx)(s.code,{children:"schema.yaml"})," in the pack.\nThey define the schema format of the pack values. The pack constraints framework auto-checks for any schema constraints\ndefined in the pack and validates the pack values. This checking occurs while creating or updating Cluster Profiles and\nClusters."]}),"\n",(0,t.jsx)(s.h2,{id:"schema-constraints",children:"Schema Constraints"}),"\n",(0,t.jsx)(s.p,{children:"Every schema constraint consists of a key name and the schema template. The key name must be the complete path of the\nparameter which is defined in the config file."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Required"})}),"\n",(0,t.jsx)(s.p,{children:"Defines whether the pack value is optional or required."}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.hostname:\n schema: '{{ required }}'\n"})}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Read only"})}),"\n",(0,t.jsx)(s.p,{children:"The pack value is not editable if marked as read only."}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.hostname:\n schema: '{{ readonly }}'\n"})}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Format"})}),"\n",(0,t.jsx)(s.p,{children:"Defines the pack value format: the value is valid only when the value format matches the format defined in the pack."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Format Syntax"})}),"\n",(0,t.jsx)(s.p,{children:"A format template consists of one or more format types along with the optional regex and number range values."}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.hostname:\n  schema: '{{ required | format \"${FORMAT_TYPE:/REGEX/ OR [NUMBER RANGE] OR [LIST_OPTIONS]}\" }}'\n"})}),"\n",(0,t.jsx)(s.admonition,{type:"warning",children:(0,t.jsxs)(s.p,{children:["The syntax of the regex accepted is the same general syntax used by Perl, Python, and other languages. More precisely,\nit is the syntax accepted by RE2 and described ",(0,t.jsx)(s.a,{href:"https://golang.org/s/re2syntax",children:"here"}),"."]})}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Format Types"})}),"\n",(0,t.jsxs)(r,{queryString:"Pack Constraints Format Types",children:[(0,t.jsxs)(n,{label:"string",value:"pack_constraint_format_string",children:[(0,t.jsx)(s.p,{children:"The string format type checks if the input value is a string and supports the regex in the template. If regex is\nspecified in the template then the input value must match the regex."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.hostname:\n  schema: '{{ format \"${string}\" }}'\nregistry.hostname:\n  schema: '{{ format \"${string:/^([a-z0-9].*)$/}\" }}'\n"})})]}),(0,t.jsxs)(n,{label:"number",value:"pack_constraint_format_number",children:[(0,t.jsx)(s.p,{children:"The number format type checks if the input value is a number, and supports the regex and the number range in the\ntemplate."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.port:\n  schema: '{{ format \"${number}\" }}'\nregistry.port:\n  schema: '{{ format \"${number:[5000-5005]}\" }}'\nregistry.port:\n  schema: '{{ format \"${number:/^(500[0-5])$/}\" }}'\n"})})]}),(0,t.jsxs)(n,{label:"boolean",value:"pack_constraint_format_boolean",children:[(0,t.jsx)(s.p,{children:"The bool format type checks if the input value is true or false."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.private:\n  schema: '{{ format \"${boolean}\" }}'\n"})})]}),(0,t.jsxs)(n,{label:"password",value:"pack_constraint_format_password",children:[(0,t.jsx)(s.p,{children:"The password format is a string type with masked values in the pack parameters of Cluster profiles and Clusters."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.password:\n  schema: '{{ format \"${password}\" }}'\nregistry.password:\n  schema: '{{ format \"${password:/^([a-z0-9].*)$/}\" }}'\n"})})]}),(0,t.jsxs)(n,{label:"list",value:"pack_constraint_format_list",children:[(0,t.jsx)(s.p,{children:"The list format checks if the input value matches with any of the options specified in the template."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.type:\n schema: '{{ format \"${list:[PACK,GIT,CHART]}\" }}'\n"})})]}),(0,t.jsxs)(n,{label:"ipv4",value:"pack_constraint_format_ipv4",children:[(0,t.jsx)(s.p,{children:"The ipv4 format type checks if the input value is a valid ipv4."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.hostIp:\n  schema: '{{ format \"${ipv4}\" }}'\n"})})]}),(0,t.jsxs)(n,{label:"version",value:"pack_constraint_format_version",children:[(0,t.jsx)(s.p,{children:"The version format type checks if the input value is a semantic version."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"registry.version:\n  schema: '{{ required | format \"${version}\" }}'\n"})})]}),(0,t.jsxs)(n,{label:"hints",value:"pack_constraint_format_hints",children:[(0,t.jsx)(s.p,{children:"Hints are optional short descriptions of the parameter. If defined in the schema template, these descriptions are\nvisible in the UI while configuring the pack parameters in the Profile or the Cluster. One or more descriptions can be\ncombined by using the pipe(|) separator."}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'registry.type:\n schema: \'{{ hints "description A" "description B" }}\'\n'})})]})]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Examples"})}),"\n",(0,t.jsx)(s.p,{children:"Schema constraints can be combined to support multiple validations using a single template."}),"\n",(0,t.jsxs)(r,{queryString:"Pack Constraints Examples",children:[(0,t.jsxs)(n,{label:"IP Range",value:"pack_constraint_example_iprange",children:[(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'registry.addresses.$[]:\n schema: \'{{ required | format "${ipv4} - ${ipv4}" | hints "ip pool range"}}\'\n'})}),(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.code,{children:"registry.addresses.$[]"})," is an array data type in the config file. The schema template defines that the value is\nrequired and the format must match - ",(0,t.jsx)(s.code,{children:"${ipv4} - ${ipv4}"})]}),(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.strong,{children:"Examples"}),":"]}
1),(0,t.jsx)(s.p,{children:"10.10.10.10 - 10.10.10.255 \u2192 valid"}),(0,t.jsx)(s.p,{children:"10.10.10.10 \u2192 invalid"}),(0,t.jsx)(s.p,{children:"10.10.10.10-10.10.10.255 \u2192 invalid"})]}),(0,t.jsxs)(n,{label:"String regex",value:"pack_constraint_example_stringregex",children:[(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"storageType:\n schema: '{{ required | format \"${string}, ${string:/size=\\d+/}\" }}'\n"})}),(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.strong,{children:"Examples"}),":"]}),(0,t.jsx)(s.p,{children:"type-zeroedthick, size=150 \u2192 valid"}),(0,t.jsx)(s.p,{children:"type-zeroedthick, size=150 \u2192 invalid"}),(0,t.jsx)(s.p,{children:"type-zeroedthick, size=s \u2192 invalid"})]})]}),"\n",(0,t.jsx)(s.h2,{id:"pack-dependency-constraints",children:"Pack Dependency Constraints"}),"\n",(0,t.jsx)(s.p,{children:"Spectro Cloud provides the flexibility to choose any pack of any version in the profile. Clusters are deployed based on\nthe packs selected in the profile. While this works for most of the cases, it is sometimes required to select a minimum\nor maximum pack version, or to have dependencies between the packs to ensure the Kubernetes cluster is deployed\nsuccessfully as desired."}),"\n",(0,t.jsxs)(s.p,{children:["Pack dependency constraints are the rules defined in the pack metadata file ",(0,t.jsx)(s.code,{children:"pack.json"}),". They are used to define the\nminimum and maximum supported versions, and also to specify which pack is required or not supported. The pack\nconstraints framework auto-checks for any schema constraints defined in the pack and validates the pack values. This\nchecking occurs while creating or updating Cluster Profiles and Clusters."]}),"\n",(0,t.jsx)(s.h2,{id:"pack-metadata-json",children:"Pack metadata JSON"}),"\n",(0,t.jsxs)(s.p,{children:["Pack dependency constraints must be defined in the ",(0,t.jsx)(s.code,{children:"pack.json"})," file. The sample pack metadata shown below defines the\ndependencies under ",(0,t.jsx)(s.code,{children:"constraints"})," key."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-json",children:'{\n  "addonType": "system app",\n  "cloudTypes": ["all"],\n  "displayName": "Test Pack",\n  "kubeManifests": [],\n  "layer": "addon",\n  "name": "pack-constraints-test",\n  "version": "1.0.0",\n  "constraints": {\n    "dependencies": [\n      {\n        "packName": "vault",\n        "layer": "addon",\n        "minVersion": "0.6.0",\n        "maxVersion": "",\n        "type": "optional"\n      },\n      {\n        "packName": "csi-vsphere-volume",\n        "layer": "csi",\n        "minVersion": "1.0.0",\n        "maxVersion": "",\n        "type": "notSupported"\n      },\n      {\n        "packName": "kubernetes",\n        "layer": "k8s",\n        "minVersion": "1.17.0",\n        "maxVersion": "1.18.6",\n        "type": "required"\n      }\n    ]\n  }\n}\n'})}),"\n",(0,t.jsx)(s.admonition,{type:"warning",children:(0,t.jsx)(s.p,{children:"If the minimum and maximum versions are not mentioned, the validation is skipped."})}),"\n",(0,t.jsx)(s.h2,{id:"pack-dependency-attributes",children:"Pack Depen
1dency Attributes"}),"\n",(0,t.jsxs)(s.p,{children:["A pack can have one or more dependencies defined in the ",(0,t.jsx)(s.code,{children:"dependencies"})," array. Each dependency consists of the following\nattributes."]}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Attribute"}),(0,t.jsx)(s.th,{children:"Description"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"packName"})}),(0,t.jsx)(s.td,{children:"Name of the dependent pack."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"layer"})}),(0,t.jsxs)(s.td,{children:["The layer type of the dependent pack. Refer to the ",(0,t.jsx)(s.a,{href:"#layer-types",children:"Layer Types"})," section to learn more."]})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"minVersion"})}),(0,t.jsx)(s.td,{children:"Minimum supported dependent pack version, any version below the minimum version is not valid."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"maxVersion"})}),(0,t.jsx)(s.td,{children:"Maximum supported dependent pack version, any version above the maximum version is not valid."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"type"})}),(0,t.jsxs)(s.td,{children:["The defined type for the dependency. Refer to the ",(0,t.jsx)(s.a,{href:"#dependency-types",children:"Dependency Types"})," section to learn more."]})]})]})]}),"\n",(0,t.jsxs)(s.p,{children:["In the example code snippet from earlier, the three dependent packs are identified by unique pack names such as ",(0,t.jsx)(s.code,{children:"vault"}),",\n",(0,t.jsx)(s.code,{children:"csi-vsphere-volume"}),", and ",(0,t.jsx)(s.code,{children:"kubernetes"}),". A ",(0,t.jsx)(s.code,{children:"minVersion"}),", ",(0,t.jsx)(s.code,{children:"maxVersion"}),", and ",(0,t.jsx)(s.code,{children:"type"})," are defined for each dependent pack."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-json",metastring:"{3,10,17} hideClipboard",children:'"dependencies": [\n    {\n      "packName": "vault",\n      "layer": "addon",\n      "minVersion": "0.6.0",\n      "maxVersion": "",\n      "type": "optional"\n    },\n    {\n      "packName": "csi-vsphere-volume",\n      "layer": "csi",\n      "minVersion": "1.0.0",\n      "maxVersion": "",\n      "type": "notSupported"\n    },\n    {\n      "packName": "kubernetes",\n      "layer": "k8s",\n      "minVersion": "1.17.0",\n      "maxVersion": "1.18.6",\n      "type": "required"\n    }\n  ]\n'})}),"\n",(0,t.jsx)(s.h4,{id:"layer-types",children:"Layer Types"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"layer"})," attribute defines the layer where the dependent pack can be found in the Cluster Profile. The following\ntable lists the different layer types."]}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Layer"}),(0,t.jsx)(s.th,{children:"Description"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"os"})}),(0,t.jsxs)(s.td,{children:["The dependent pack can only be found in the operating system layer of the Cluster Profile. The ",(0,t.jsx)(s.code,{children:"os"})," layer contains packs such as Ubuntu, CentOS or Bring Your Own OS (BYOOS)."]})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"k8s"})}),(0,t.jsxs)(s.td,{children:["The dependent pack can only be found in the Kubernetes layer of the Cluster Profile. The ",(0,t.jsx)(s.code,{children:"k8s"})," layer contains packs such as ",(0,t.jsx)(a,{text:"Palette eXtended Kubernetes (PXK)",url:"/integrations/packs/?pack=kubernetes"}),", RKE2, k3s or MicroK8s."]})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"cni"})}),(0,t.jsxs)(s.td,{children:["The dependent pack can only be found in the network layer of the Cluster Profile. The ",(0,t.jsx)(s.code,{children:"cni"})," layer contains packs such as Calico, Cilium, Flannel and Antrea."]})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"csi"})}),(0,t.jsxs)(s.td,{children:["The dependent pack can only be found in the storage layer of the Cluster Profile. The ",(0,t.jsx)(s.code,{children:"csi"})," layer contains packs such as vSphere CSI, Amazon EBS CSI, Amazon EFS, Azure Disk and Portworx."]})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"addon"})}),(0,t.jsxs)(s.td,{children:["The dependent pack can only be found in the add-on layers of the Cluster Profile. The types of packs include ",(0,t.jsx)(s.code,{children:"logging"}),", ",(0,t.jsx)(s.code,{children:"monitoring"}),", ",(0,t.jsx)(s.code,{children:"load balancer"}),", ",(0,t.jsx)(s.code,{children:"authentication"}),", ",(0,t.jsx)(s.code,{children:"ingress"}),", ",(0,t.jsx)(s.code,{children:"security"}),", ",(0,t.jsx)(s.code,{children:"ai"}),", ",(0,t.jsx)(s.code,{children:"app services"}),", ",(0,t.jsx)(s.code,{children:"network"}),", ",(0,t.jsx)(s.code,{children:"storage"}),", ",(0,t.jsx)(s.code,{children:"registry"}),", ",(0,t.jsx)(s.code,{children:"servicemesh"}),", and ",(0,t.jsx)(s.code,{children:"system app"}),". The ",(0,t.jsx)(s.code,{children:"addon"})," layer contains packs such as ArgoCD, Vault, Nginx, and many more."]})]})]})]}),"\n",(0,t.jsx)(s.h4,{id:"dependency-types",children:"Dependency Types"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"type"})," attribute defines the type of dependency. The following table lists the different dependency types."]}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Type"}),(0,t.jsx)(s.th,{children:"Description"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"optional"})}),(0,t.jsxs)(s.td,{children:["The dependent pack is optional but validates minimum or maximum versions if the pack is selected. In the example, the ",(0,t.jsx)(s.code,{children:"vault"})," pack is optional."]})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"required"})}),(0,t.jsxs)(s.td,{children:["The dependent pack is mandatory and must contain a version within the minimum or maximum supported versions, if defined. In the example, the ",(0,t.jsx)(s.code,{children:"kubernetes"})," pack is required with a minimum version of ",(0,t.jsx)(s.code,{children:"1.17.0"})," and a max version of ",(0,t.jsx)(s.code,{children:"1.18.6"}),". Any Kubernetes version below ",(0,t.jsx)(s.code,{children:"1.17.0"})," and above ",(0,t.jsx)(s.code,{children:"1.18.6"}
1)," is not valid."]})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"notSupported"})}),(0,t.jsxs)(s.td,{children:["The pack versions within the range of the mentioned minimum and maximum are not supported. The ",(0,t.jsx)(s.code,{children:"csi-vsphere-volume"})," pack is not supported if the version selected falls within the min and max versions."]})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"pack-resource-constraints",children:"Pack Resource Constraints"}),"\n",(0,t.jsx)(s.p,{children:"A successful Kubernetes Cluster deployment is possible only when the cluster has sufficient hardware requirements. We\nconsider the CPU, Memory, and Disk size as the hardware requirements. The minimum resource requests can be varied\ndepending on the workload to be deployed in the cluster. Spectro Cloud users are allowed to select the desired instance\ntype, and the disk size while configuring the machine pool in the Cluster deployment procedure. If the user selects the\ninstance type which does not satisfy the minimum CPU or Memory or Disk size requirements, then there is a high\nprobability that the cluster deployment may not succeed due to insufficient CPU or Memory or Disk size."}),"\n",(0,t.jsxs)(s.p,{children:["Pack Resource Constraints are a set of rules defined in the pack metadata ",(0,t.jsx)(s.code,{children:"pack.json"})," to specify the minimum CPU,\nMemory, and Disk size requirements. The pack constraints framework auto-checks the resource constraints and validates\nthe user-selected instance type specifications before the cluster is submitted for deployment. The total input resource\ncapacity is evaluated against the machine pool size with the actual hardware specifications of a selected instance type."]}),"\n",(0,t.jsx)(s.h2,{id:"pack-metadata-json-1",children:"Pack metadata JSON"}),"\n",(0,t.jsxs)(s.p,{children:["Pack resource constraints must be defined in the ",(0,t.jsx)(s.code,{children:"pack.json"})," file. The sample pack metadata is shown below to define the\n",(0,t.jsx)(s.code,{children:"resources"})," under ",(0,t.jsx)(s.code,{children:"constraints"})," key."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-json",children:'{\n  "addonType": "system app",\n  "cloudTypes": ["all"],\n  "displayName": "Test Pack",\n  "kubeManifests": [],\n  "layer": "addon",\n  "name": "pack-constraints-test",\n  "version": "1.0.0",\n  "constraints": {\n    "resources": [\n      {\n        "type": "cpu",\n        "minLimit": 2000,\n        "components": [\n          {\n            "resourceRequestParamRef": "requests.cpu",\n            "replicaCountParamRef": "replicas",\n            "scheduleType": "all"\n          }\n        ]\n      },\n      {\n        "type": "memory",\n        "minLimit": 2048,\n        "components": [\n          {\n            "resourceRequestParamRef": "requests.memory",\n            "replicaCountParamRef": "replicas",\n            "scheduleType": "worker"\n          }\n        ]\n      },\n      {\n        "type": "diskSize",\n        "minLimit": 10\n      }\n    ]\n  }\n}\n'})}),"\n",(0,t.jsx)(s.h2,{id:"pack-resources-attributes",children:"Pack Resources Attributes"}),"\n",(0,t.jsxs)(r,{queryString:"Pack Resource Attributes",children:[(0,t.jsxs)(n,{label:"type",value:"pack_resources_type",children:[(0,t.jsx)(s.p,{children:"The type of resource"}),(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"CPU"}),"\n",(0,t.jsx)(s.li,{children:"Memory"}),"\n",(0,t.jsx)(s.li,{children:"Disk size"}),"\n"]})]}),(0,t.jsxs)(n,{label:"minimum limit",value:"pack_resources_minLimit",children:[(0,t.jsx)(s.p,{children:"The minimum limit of the resource will be considered during the machine pool validation. The resource limit value is\nrequired to have the below unit depending on the resource type. Any change of unit will cause inaccurate computation of\nthe total minimum requirement."}),(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"CPU - Millicore (m)"}),"\n",(0,t.jsx)(s.li,{children:"Memory - Mibibyte (Mi)"}),"\n",(0,t.jsx)(s.li,{children:"Disk size - Gigabyte (GB)"}),"\n"]})]}),(0,t.jsxs)(n,{label:"components",value:"pack_resources_components",children:[(0,t.jsxs)(s.p,{children:["The minimum limit is the minimum resource requirement for each worker pool in the cluster. This value is sufficient for\nthe basic resource validation, but in some cases where the pack contains one or more associated components, then each\ncomponent can define its CPU or memory resource requests in the config file ",(0,t.jsx)(s.code,{children:"values.yaml"}),". In this case, a single\n",(0,t.jsx)(s.code,{children:"minLimit"})," value is not sufficient as the minimum requirements can be different for each component."]}),(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsxs)(s.p,{children:["If the components are defined then ",(0,t.jsx)(s.code,{children:"minLimit"}
1)," is ignored during resource validation."]})}),(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"components"})," field is an array of the component which consists of these attributes."]}),(0,t.jsxs)(r,{queryString:"Pack Resource Components",children:[(0,t.jsx)(n,{label:"resourceRequestParamRef",value:"pack_resources_resourceRequestParamRef",children:(0,t.jsxs)(s.p,{children:["Resource requests and limits can be defined in the pack ",(0,t.jsx)(s.code,{children:"values.yaml"}),". It is required for the pack constraints framework\nto know the parameter name from where the resource request value can be read during the resource validation. So, the\n",(0,t.jsx)(s.code,{children:"resourceRequestParamRef"})," is the configuration parameter name of the resource request defined in the ",(0,t.jsx)(s.code,{children:"values.yaml"}),"."]})}),(0,t.jsx)(n,{label:"replicaCountParamRef",value:"pack_resources_replicaCountParamRef",children:(0,t.jsxs)(s.p,{children:["The Kubernetes pod can run in one or more replicas based on the replica count configured in the ",(0,t.jsx)(s.code,{children:"values.yaml"})," file. The\nresource request values defined in ",(0,t.jsx)(s.code,{children:"values.yaml"})," are for one replica, and the requests must be multiplied by the number\nof replicas which gives the actual minimum requirement. So, the ",(0,t.jsx)(s.code,{children:"replicaCountParamRef"})," is the configuration parameter\nname of the replica count defined in the ",(0,t.jsx)(s.code,{children:"values.yaml"})]})}),(0,t.jsxs)(n,{label:"scheduleType",value:"pack_resources_scheduleType",children:[(0,t.jsx)(s.p,{children:"Kubernetes provides a way to schedule the pods on the control plane and worker nodes. Pack Constraints framework must\nknow where the pods are scheduled because the resource validation validates only the control plane machine pool when the\npods are scheduled on control plane nodes. Similarly, if the pods are scheduled on worker nodes, then only the worker\nmachine pool will be validated. In the case of daemon sets, the pods are scheduled in both control plane and worker\nnodes, and the framework validates both control plane and worker machine pool configurations before the cluster is\nsubmitted for deployment."}),(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.code,{children:"control-plane"})," - pods are scheduled only on control plane nodes"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.code,{children:"worker"})," - pods are scheduled only on worker nodes"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.code,{children:"all"})," - pods are scheduled on both control plane and worker nodes"]}),"\n"]})]})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"pack-presets",children:"Pack Presets"}),"\n",(0,t.jsxs)(s.p,{children:["Pack Presets are the predefined values in a file called ",(0,t.jsx)(s.code,{children:"presets.yaml"})," in the pack. It contains an array of the presets\nfor the pack, and is visible in the pack parameters of the Cluster profile and the Cluster. Users can select any preset\nfrom the available pack presets, and the predefined values of a selected preset are applied automatically by the Spectro\nCloud UI. Presets make pack configuration much easier as multiple pack values are updated at a time and the user does\nnot need to understand all the configuration parameters which get changed depending on various factors."]}),"\n",(0,t.jsx)(s.h2,{id:"presets-metadata-yaml",children:"Presets Metadata YAML"}),"\n",(0,t.jsxs)(s.p,{children:["This ",(0,t.jsx)(s.code,{children:"presets.yaml"})," shows two presets"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.code,{children:"privatePackRegistry"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.code,{children:"publicPackRegistry"})}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"with a different set of pre-defined values."}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'presets:\n- name: "privatePackRegistry"\n  displayName: "Private Registry"\n  group: "registry"\n  remove: ["registry.ingress.host"]\n  add: |\n    registry:\n      private: true\n      type: "PACK"\n      host:\n       ip: "127.0.0.1"\n       port: 5000\n- name: "publicPackRegistry"\n  displayName: "Public Registry"\n  group: "registry"\n  remove: ["registry.ingress.host"]\n  add: |\n    registry:\n      private: false\n      type: "PACK"\n      host:\n       ip: "13.233.2.255"\n       port: 80\n'})}),"\n",(0,t.jsx)(s.h2,{id:"preset-attributes",children:"Preset Attributes"}),"\n",(0,t.jsxs)(r,{queryString:"Preset Attributes",children:[(0,t.jsx)(n,{label:"name",value:"preset_attributes_name",children:(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.em,{children:"Name of the preset."})," It must be unique."]})}),(0,t.jsx)(n,{label:"displayName",value:"preset_attributes_displayName",children:(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.em,{children:"Name of the preset."})," It is visible in the parameters configuration"]})}),(0,t.jsx)(n,{label:"remove",value:"preset_attributes_remove",children:(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.em,{children:"An array of parameter names."}
1)," These are removed from the pack values when a preset is selected."]})}),(0,t.jsx)(n,{label:"add",value:"preset_attributes_add",children:(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.em,{children:"A set of values in YAML format."})," These are added/updated in the pack values when a preset is selected."]})}),(0,t.jsx)(n,{label:"group",value:"preset_attributes_group",children:(0,t.jsx)(s.p,{children:"One or more presets can be categorized into a common group, but only one preset can be selected from the same group of\npresets."})})]}),"\n",(0,t.jsx)(s.h2,{id:"pack-macros",children:"Pack Macros"}),"\n",(0,t.jsx)(s.p,{children:"Pack macros are the variables defined in the Cluster profile or in Cluster pack values, and these variables are resolved\nonly at the cluster deployment time."}),"\n",(0,t.jsx)(s.h2,{id:"types-of-macros",children:"Types of Macros"}),"\n",(0,t.jsxs)(r,{queryString:"Pack Macros Types",children:[(0,t.jsxs)(n,{label:"System Macros",value:"system_macros",children:[(0,t.jsx)(s.p,{children:"System macros are variables defined by the system. Users are allowed to use these variables and the system is capable of\nresolving all the variables to values at the time of cluster deployment."}),(0,t.jsxs)(r,{queryString:"System Macros",children:[(0,t.jsxs)(n,{label:"Syntax",value:"system_macros_syntax",children:[(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'user:\n name: "{{ .spectro.system.[VARIABLE_NAME] }}"\n'})}),(0,t.jsx)(s.h3,{id:"supported-variables",children:"Supported Variables"}),(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Macro"}),(0,t.jsx)(s.th,{children:"Description"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.user.name}}"})}),(0,t.jsx)(s.td,{children:"The name of the user currently logged in."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.user.uid}}"})}),(0,t.jsx)(s.td,{children:"The unique identifier of the user currently logged in."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.user.email}}"})}),(0,t.jsx)(s.td,{children:"The email address of the user currently logged in."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.tenant.uid}}"})}),(0,t.jsx)(s.td,{children:"The unique identifier of the current tenant."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.project.name}}"})}),(0,t.jsx)(s.td,{children:"The name of the project."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.project.uid}}"})}),(0,t.jsx)(s.td,{children:"The unique identifier of the project."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.clusterprofile.name}}"})}),(0,t.jsx)(s.td,{children:"The name of the cluster profile associated with the current project."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.clusterprofile.uid}}"})}),(0,t.jsx)(s.td,{children:"The unique identifier of the cluster profile the pack is part of."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.clusterprofile.version}}"})}),(0,t.jsx)(s.td,{children:"The current version of the cluster profile the pack is part of."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.cluster.name}}"})}),(0,t.jsx)(s.td,{children:"The name of the cluster."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.cluster.uid}}"})}),(0,t.jsx)(s.td,{children:"The unique identifier of the cluster."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.cloudaccount.name}}"})}),(0,t.jsx)(s.td,{children:"The name of the cloud account associated with the current project."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.cloudaccount.uid}}"})}),(0,t.jsx)(s.td,{children:"The unique identifier of the cloud account associated with the current project."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.kubernetes.version}}"})}),(0,t.jsx)(s.td,{children:"The version of Kubernetes currently running on the cluster."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.reverseproxy.server}}"})}),(0,t.jsx)(s.td,{children:"The hostname of the reverse proxy server."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.reverseproxy.port}}"})}),(0,t.jsx)(s.td,{children:"The port number of the reverse proxy server."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.reverseproxy.protocol}}"})}),(0,t.jsx)(s.td,{children:"The protocol used by the reverse proxy server, either HTTP or HTTPS."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.reverseproxy.vhostport}}"})}),(0,t.jsx)(s.td,{children:"The port number used by the virtual host on the reverse proxy server."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.cloud.type }}"})}),(0,t.jsx)(s.td,{children:"The type of cloud provider being used, such as AWS, GCP, Azure or other providers."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.cloud.region }}"})}),(0,t.jsx)(s.td,{children:"The region where the cloud resources are located."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.clusterprofile.infra.name}}"})}),(0,t.jsx)(s.td,{children:"The name of the cluster profile."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.clusterprofile.infra.uid}}"})}),(0,t.jsx)(s.td,{children:"The unique identifier of the cluster profile."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.clusterprofile.infra.version}}"})}),(0,t.jsx)(s.td,{children:"The version of the cluster profile."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"{{.spectro.system.cluster.kubevip}}"})}),(0,t.jsx)(s.td,{children:"The IP address of the virtual IP (VIP) assigned to the cluster and load balancer for the control plane. This macro is only available for Edge and vSphere cluster deployments."})]})]})]})]}),(0,t.jsx)(n,{label:"Examples",value:"system_macros_examples",children:(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'user:\n name: "{{ .spectro.system.user.name }}"\n uid: "{{ .spectro.system.user.uid}}"\n'})})})]})]}),(0,t.jsxs)(n,{label:"Pack Reference Macros",value:"pack_reference_macros",children:[(0,t.jsx)(s.p,{children:"Pack reference macros are custom variables that must be defined in a pack and then can be used as a variable in any\npack. If the variable is not defined with a value, then the default value is applied, if specified. If the default value\nis not specified, then the variable will be resolved to an empty value."}),(0,t.jsxs)(r,{queryString:"Pack Reference Macros",children:[(0,t.jsxs)(n,{label:"Syntax",value:"reference_macros_syntax",children:[(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'k8s:\n version: "{{ .spectro.pack.[PACK_NAME].[VARIABLE_NAME] }}"\n'})}),(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.code,{children:"PACK_NAME"})," - the name of the pack where the variable is defined"]}),(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.code,{children:"VARIABLE_NAME"})," - the fully qualified name of the variable defined in the pack"]})]}),(0,t.jsxs)(n,{label:"Examples",value:"reference_macros_examples",children:[(0,t.jsx)(s.p,{children:"Referencing Kubernetes pack variable version in CentOS pack values:"}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",metastring:'title="CentOS values.yaml"',children:'k8s:\n version: "{{ .spectro.pack.kubernetes.version }}"\n'})}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",metastring:'title="Kubernetes values.yaml"',children:"version: 1.18.0\n"})})]})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"additional-capabilities",children:"Additional Capabilities"}),"\n",(0,t.jsx)(s.h3,{id:"sprig-template-functions",children:"Sprig Template Functions"}),"\n",(0,t.jsxs)(s.p,{children:["Users are allowed to use the ",(0,t.jsx)(s.a,{href:"http://masterminds.github.io/sprig/",children:"sprig template functions"})," to modify the resolved\nvariable value."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Examples"})}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'user:\n name: "{{ .spectro.system.user.name | upper }}"\n'})}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.code,{children:"upper"})," - sprig template function which converts resolved user name to upper case"]}),"\n",(0,t.jsx)(s.h3,{id:"how-to-set-the-default-value",children:"How to set the default value?"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'k8s:\n version: "{{ .spectro.pack.kubernetes.version | default \\"1.19.0\\"}}"\n'})}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsxs)(s.p,{children:["If the variable ",(0,t.jsx)(s.code,{children:"version"})," is not defined in the pack ",(0,t.jsx)(s.code,{children:"kubernetes"}),", then the default value ",(0,t.jsx)(s.code,{children:"1.19.0"})," will be applied at\ndeployment. In case the default value is not specified then the empty value will be applied."]})})]})}function h(e={}){let{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}function p(e,s){throw Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},884429:function(e,s,n){n.d(s,{R:()=>a,x:()=>c});var r=n(296540);let t={},i=r.createContext(t);function a(e){let s=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.