diff --git a/pkg/cmd/hgctl/helm/profile.go b/pkg/cmd/hgctl/helm/profile.go index f94dfea29..6f0acb488 100644 --- a/pkg/cmd/hgctl/helm/profile.go +++ b/pkg/cmd/hgctl/helm/profile.go @@ -17,6 +17,7 @@ package helm import ( "errors" "fmt" + "regexp" "strings" "istio.io/istio/operator/pkg/util" @@ -84,9 +85,10 @@ func (p ProfileGlobal) Validate(install InstallMode) []error { } type ProfileConsole struct { - Port uint32 `json:"port,omitempty"` - Replicas uint32 `json:"replicas,omitempty"` - O11yEnabled bool `json:"o11YEnabled,omitempty"` + Port uint32 `json:"port,omitempty"` + Replicas uint32 `json:"replicas,omitempty"` + O11yEnabled bool `json:"o11YEnabled,omitempty"` + Resources Resource `json:"resources,omitempty"` } func (p ProfileConsole) SetFlags(install InstallMode) ([]string, error) { @@ -112,14 +114,31 @@ func (p ProfileConsole) Validate(install InstallMode) []error { } } + // set default value + if p.Resources.Requests.CPU == "" { + p.Resources.Requests.CPU = "250m" + } + if p.Resources.Requests.Memory == "" { + p.Resources.Requests.Memory = "512Mi" + } + if p.Resources.Limits.CPU == "" { + p.Resources.Limits.CPU = "2000m" + } + if p.Resources.Limits.Memory == "" { + p.Resources.Limits.Memory = "2048Mi" + } + + errs = append(errs, p.Resources.Validate()...) + return errs } type ProfileGateway struct { - Replicas uint32 `json:"replicas,omitempty"` - HttpPort uint32 `json:"httpPort,omitempty"` - HttpsPort uint32 `json:"httpsPort,omitempty"` - MetricsPort uint32 `json:"metricsPort,omitempty"` + Replicas uint32 `json:"replicas,omitempty"` + HttpPort uint32 `json:"httpPort,omitempty"` + HttpsPort uint32 `json:"httpsPort,omitempty"` + MetricsPort uint32 `json:"metricsPort,omitempty"` + Resources Resource `json:"resources,omitempty"` } func (p ProfileGateway) SetFlags(install InstallMode) ([]string, error) { @@ -149,11 +168,29 @@ func (p ProfileGateway) Validate(install InstallMode) []error { errs = append(errs, errors.New("gateway.MetricsPort need be large than zero")) } } + + // set default value + if p.Resources.Requests.CPU == "" { + p.Resources.Requests.CPU = "2000m" + } + if p.Resources.Requests.Memory == "" { + p.Resources.Requests.Memory = "2048Mi" + } + if p.Resources.Limits.CPU == "" { + p.Resources.Limits.CPU = "2000m" + } + if p.Resources.Limits.Memory == "" { + p.Resources.Limits.Memory = "2048Mi" + } + + errs = append(errs, p.Resources.Validate()...) + return errs } type ProfileController struct { - Replicas uint32 `json:"replicas,omitempty"` + Replicas uint32 `json:"replicas,omitempty"` + Resources Resource `json:"resources,omitempty"` } func (p ProfileController) SetFlags(install InstallMode) ([]string, error) { @@ -171,6 +208,23 @@ func (p ProfileController) Validate(install InstallMode) []error { errs = append(errs, errors.New("controller.replica need be large than zero")) } } + + // set default value + if p.Resources.Requests.CPU == "" { + p.Resources.Requests.CPU = "500m" + } + if p.Resources.Requests.Memory == "" { + p.Resources.Requests.Memory = "2048Mi" + } + if p.Resources.Limits.CPU == "" { + p.Resources.Limits.CPU = "1000m" + } + if p.Resources.Limits.Memory == "" { + p.Resources.Limits.Memory = "2048Mi" + } + + errs = append(errs, p.Resources.Validate()...) + return errs } @@ -248,14 +302,62 @@ func (p *Profile) ValuesYaml() (string, error) { setFlags = append(setFlags, controllerFlags...) valueOverlayYAML := "" - if p.Values != nil { - out, err := yaml.Marshal(p.Values) - if err != nil { - return "", err - } - valueOverlayYAML = string(out) + if p.Values == nil { + p.Values = make(map[string]any) } + resourceMap := make(map[string]any) + resourceMap["higress-core"] = map[string]interface{}{ + "controller": map[string]interface{}{ + "resources": map[string]interface{}{ + "requests": map[string]interface{}{ + "cpu": p.Controller.Resources.Requests.CPU, + "memory": p.Controller.Resources.Requests.Memory, + }, + "limits": map[string]interface{}{ + "cpu": p.Controller.Resources.Limits.CPU, + "memory": p.Controller.Resources.Limits.Memory, + }, + }, + }, + "gateway": map[string]interface{}{ + "resources": map[string]interface{}{ + "requests": map[string]interface{}{ + "cpu": p.Gateway.Resources.Requests.CPU, + "memory": p.Gateway.Resources.Requests.Memory, + }, + "limits": map[string]interface{}{ + "cpu": p.Gateway.Resources.Limits.CPU, + "memory": p.Gateway.Resources.Limits.Memory, + }, + }, + }, + } + resourceMap["higress-console"] = map[string]interface{}{ + "resources": map[string]interface{}{ + "requests": map[string]interface{}{ + "cpu": p.Console.Resources.Requests.CPU, + "memory": p.Console.Resources.Requests.Memory, + }, + "limits": map[string]interface{}{ + "cpu": p.Console.Resources.Limits.CPU, + "memory": p.Console.Resources.Limits.Memory, + }, + }, + } + + resourceYAML, err := yaml.Marshal(resourceMap) + if err != nil { + return "", err + } + + out, err := yaml.Marshal(p.Values) + if err != nil { + return "", err + } + + valueOverlayYAML, err = util.OverlayYAML(string(resourceYAML), string(out)) + flagsYAML, err := overlaySetFlagValues("", setFlags) if err != nil { return "", err @@ -343,3 +445,54 @@ func ToString(errors []error, separator string) string { } return out } + +type Resource struct { + Requests Requests `json:"requests,omitempty"` + Limits Limits `json:"limits,omitempty"` +} + +type Requests struct { + CPU string `json:"cpu,omitempty"` + Memory string `json:"memory,omitempty"` +} + +type Limits struct { + CPU string `json:"cpu,omitempty"` + Memory string `json:"memory,omitempty"` +} + +func (r Resource) Validate() []error { + errs := make([]error, 0) + + r.Requests.CPU = strings.ReplaceAll(r.Requests.CPU, " ", "") + r.Requests.Memory = strings.ReplaceAll(r.Requests.Memory, " ", "") + r.Limits.CPU = strings.ReplaceAll(r.Limits.CPU, " ", "") + r.Limits.Memory = strings.ReplaceAll(r.Limits.Memory, " ", "") + + if !isValidK8SResourceFormat(r.Requests.CPU) { + errs = append(errs, fmt.Errorf("requests CPU has invalid format")) + } + if !isValidK8SResourceFormat(r.Requests.Memory) { + errs = append(errs, fmt.Errorf("requests memory has invalid format")) + } + if !isValidK8SResourceFormat(r.Limits.CPU) { + errs = append(errs, fmt.Errorf("limits CPU has invalid format")) + } + if !isValidK8SResourceFormat(r.Limits.Memory) { + errs = append(errs, fmt.Errorf("limits memory has invalid format")) + } + return errs +} + +func isValidK8SResourceFormat(resource string) bool { + pattern := `^\d+((n|u|m|k|Ki|M|Mi|G|Gi|T|Ti|P|Pi|E|Ei)?)$` + match, _ := regexp.MatchString(pattern, resource) + if !match { + return false + } + + if len(resource) == 0 || resource[0] == '-' || resource[0] == '0' { + return false + } + return true +} diff --git a/pkg/cmd/hgctl/manifests/profiles/_all.yaml b/pkg/cmd/hgctl/manifests/profiles/_all.yaml index 8a92e68b4..8c4c57a50 100644 --- a/pkg/cmd/hgctl/manifests/profiles/_all.yaml +++ b/pkg/cmd/hgctl/manifests/profiles/_all.yaml @@ -10,15 +10,36 @@ console: port: 8080 replicas: 1 o11yEnabled: false + resources: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: 2000m + memory: 2048Mi gateway: replicas: 1 httpPort: 80 httpsPort: 443 metricsPort: 15020 + resources: + requests: + cpu: 2000m + memory: 2048Mi + limits: + cpu: 2000m + memory: 2048Mi controller: replicas: 1 + resources: + requests: + cpu: 500m + memory: 2048Mi + limits: + cpu: 1000m + memory: 2048Mi storage: url: nacos://127.0.0.1:8848 # file://opt/higress/conf diff --git a/pkg/cmd/hgctl/manifests/profiles/k8s.yaml b/pkg/cmd/hgctl/manifests/profiles/k8s.yaml index e1e805e62..41aa5ac6c 100644 --- a/pkg/cmd/hgctl/manifests/profiles/k8s.yaml +++ b/pkg/cmd/hgctl/manifests/profiles/k8s.yaml @@ -9,12 +9,33 @@ global: console: replicas: 1 o11yEnabled: false + resources: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: 2000m + memory: 2048Mi gateway: replicas: 2 + resources: + requests: + cpu: 2000m + memory: 2048Mi + limits: + cpu: 2000m + memory: 2048Mi controller: replicas: 1 + resources: + requests: + cpu: 500m + memory: 2048Mi + limits: + cpu: 1000m + memory: 2048Mi # values passed through to helm values: diff --git a/pkg/cmd/hgctl/manifests/profiles/local-k8s.yaml b/pkg/cmd/hgctl/manifests/profiles/local-k8s.yaml index 9f6b09e34..3eb69815e 100644 --- a/pkg/cmd/hgctl/manifests/profiles/local-k8s.yaml +++ b/pkg/cmd/hgctl/manifests/profiles/local-k8s.yaml @@ -9,12 +9,33 @@ global: console: replicas: 1 o11yEnabled: true + resources: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: 2000m + memory: 2048Mi gateway: replicas: 1 + resources: + requests: + cpu: 2000m + memory: 2048Mi + limits: + cpu: 2000m + memory: 2048Mi controller: replicas: 1 + resources: + requests: + cpu: 500m + memory: 2048Mi + limits: + cpu: 1000m + memory: 2048Mi # values passed through to helm values: