Skip to content

Commit

Permalink
enable gatewayapi and reduce profile structure
Browse files Browse the repository at this point in the history
  • Loading branch information
2456868764 committed Nov 2, 2023
1 parent 1b2e900 commit 1e5dab2
Show file tree
Hide file tree
Showing 29 changed files with 19,763 additions and 139 deletions.
71 changes: 33 additions & 38 deletions pkg/cmd/hgctl/helm/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,19 @@ type Profile struct {
}

type ProfileGlobal struct {
Install InstallMode `json:"install,omitempty"`
IngressClass string `json:"ingressClass,omitempty"`
WatchNamespace string `json:"watchNamespace,omitempty"`
DisableAlpnH2 bool `json:"disableAlpnH2,omitempty"`
EnableStatus bool `json:"enableStatus,omitempty"`
EnableIstioAPI bool `json:"enableIstioAPI,omitempty"`
Namespace string `json:"namespace,omitempty"`
IstioNamespace string `json:"istioNamespace,omitempty"`
Install InstallMode `json:"install,omitempty"`
IngressClass string `json:"ingressClass,omitempty"`
EnableIstioAPI bool `json:"enableIstioAPI,omitempty"`
EnableGatewayAPI bool `json:"enableGatewayAPI,omitempty"`
Namespace string `json:"namespace,omitempty"`
}

func (p ProfileGlobal) SetFlags(install InstallMode) ([]string, error) {
sets := make([]string, 0)
if install == InstallK8s || install == InstallLocalK8s {
sets = append(sets, fmt.Sprintf("global.ingressClass=%s", p.IngressClass))
sets = append(sets, fmt.Sprintf("global.watchNamespace=%s", p.WatchNamespace))
sets = append(sets, fmt.Sprintf("global.disableAlpnH2=%t", p.DisableAlpnH2))
sets = append(sets, fmt.Sprintf("global.enableStatus=%t", p.EnableStatus))
sets = append(sets, fmt.Sprintf("global.enableIstioAPI=%t", p.EnableIstioAPI))
sets = append(sets, fmt.Sprintf("global.istioNamespace=%s", p.IstioNamespace))
sets = append(sets, fmt.Sprintf("global.enableGatewayAPI=%t", p.EnableGatewayAPI))
if install == InstallLocalK8s {
sets = append(sets, fmt.Sprintf("global.local=%t", true))
}
Expand All @@ -84,38 +78,24 @@ func (p ProfileGlobal) Validate(install InstallMode) []error {
if len(p.Namespace) == 0 {
errs = append(errs, errors.New("global.namespace can't be empty"))
}
if len(p.IstioNamespace) == 0 {
errs = append(errs, errors.New("global.istioNamespace can't be empty"))
}
}
return errs
}

type ProfileConsole struct {
Port uint32 `json:"port,omitempty"`
Replicas uint32 `json:"replicas,omitempty"`
ServiceType string `json:"serviceType,omitempty"`
Domain string `json:"domain,omitempty"`
TlsSecretName string `json:"tlsSecretName,omitempty"`
WebLoginPrompt string `json:"webLoginPrompt,omitempty"`
AdminPasswordValue string `json:"adminPasswordValue,omitempty"`
AdminPasswordLength uint32 `json:"adminPasswordLength,omitempty"`
O11yEnabled bool `json:"o11YEnabled,omitempty"`
PvcRwxSupported bool `json:"pvcRwxSupported,omitempty"`
Port uint32 `json:"port,omitempty"`
Replicas uint32 `json:"replicas,omitempty"`
AdminPasswordValue string `json:"adminPasswordValue,omitempty"`
}

func (p ProfileConsole) SetFlags(install InstallMode) ([]string, error) {
sets := make([]string, 0)
if install == InstallK8s || install == InstallLocalK8s {
sets = append(sets, fmt.Sprintf("higress-console.replicaCount=%d", p.Replicas))
sets = append(sets, fmt.Sprintf("higress-console.service.type=%s", p.ServiceType))
sets = append(sets, fmt.Sprintf("higress-console.domain=%s", p.Domain))
sets = append(sets, fmt.Sprintf("higress-console.tlsSecretName=%s", p.TlsSecretName))
sets = append(sets, fmt.Sprintf("higress-console.web.login.prompt=%s", p.WebLoginPrompt))
sets = append(sets, fmt.Sprintf("higress-console.admin.password.value=%s", p.AdminPasswordValue))
sets = append(sets, fmt.Sprintf("higress-console.admin.password.length=%d", p.AdminPasswordLength))
sets = append(sets, fmt.Sprintf("higress-console.o11y.enabled=%t", p.O11yEnabled))
sets = append(sets, fmt.Sprintf("higress-console.pvc.rwxSupported=%t", p.PvcRwxSupported))
if install == InstallLocalK8s {
sets = append(sets, fmt.Sprintf("higress-console.o11y.enabled=%t", true))
}
}
return sets, nil
}
Expand All @@ -126,10 +106,6 @@ func (p ProfileConsole) Validate(install InstallMode) []error {
if p.Replicas <= 0 {
errs = append(errs, errors.New("console.replica need be large than zero"))
}

if p.ServiceType != "ClusterIP" && p.ServiceType != "NodePort" && p.ServiceType != "LoadBalancer" {
errs = append(errs, errors.New("console.serviceType can only be set to ClusterIP, NodePort or LoadBalancer"))
}
}

if install == InstallLocalDocker {
Expand Down Expand Up @@ -232,7 +208,7 @@ func (p ProfileStorage) Validate(install InstallMode) []error {
}

if len(p.Username) > 0 && len(p.Password) == 0 || len(p.Username) == 0 && len(p.Password) > 0 {
errs = append(errs, errors.New("both nacos username and password shall be provided"))
errs = append(errs, errors.New("both nacos username and password should be provided"))
}
}
return errs
Expand All @@ -246,7 +222,6 @@ type Chart struct {

type ProfileCharts struct {
Higress Chart `json:"higress,omitempty"`
Istio Chart `json:"istio,omitempty"`
Standalone Chart `json:"standalone,omitempty"`
}

Expand Down Expand Up @@ -302,6 +277,26 @@ func (p *Profile) IstioEnabled() bool {
return false
}

func (p *Profile) GatewayAPIEnabled() bool {
if (p.Global.Install == InstallK8s || p.Global.Install == InstallLocalK8s) && p.Global.EnableGatewayAPI {
return true
}
return false
}

func (p *Profile) GetIstioNamespace() string {
if valuesGlobal, ok1 := p.Values["global"]; ok1 {
if global, ok2 := valuesGlobal.(map[string]any); ok2 {
if istioNamespace, ok3 := global["istioNamespace"]; ok3 {
if namespace, ok4 := istioNamespace.(string); ok4 {
return namespace
}
}
}
}
return ""
}

func (p *Profile) Validate() error {
errs := make([]error, 0)
errsGlobal := p.Global.Validate(p.Global.Install)
Expand Down
88 changes: 79 additions & 9 deletions pkg/cmd/hgctl/helm/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ type RendererOptions struct {
Name string
Namespace string

// fields for LocalRenderer
// fields for LocalChartRenderer and LocalFileRenderer
FS fs.FS
Dir string

Expand Down Expand Up @@ -174,14 +174,84 @@ func WithRepoURL(repo string) RendererOption {
}
}

// LocalRenderer load chart from local file system
type LocalRenderer struct {
// LocalFileRenderer load yaml files from local file system
type LocalFileRenderer struct {
Opts *RendererOptions
filesMap map[string]string
Started bool
}

func NewLocalFileRenderer(opts ...RendererOption) (Renderer, error) {
newOpts := &RendererOptions{}
for _, opt := range opts {
opt(newOpts)
}

return &LocalFileRenderer{
Opts: newOpts,
filesMap: make(map[string]string),
}, nil
}

func (l *LocalFileRenderer) Init() error {
fileNames, err := getFileNames(l.Opts.FS, l.Opts.Dir)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("chart of component %s doesn't exist", l.Opts.Name)
}
return fmt.Errorf("getFileNames err: %s", err)
}
for _, fileName := range fileNames {
data, err := fs.ReadFile(l.Opts.FS, fileName)
if err != nil {
return fmt.Errorf("ReadFile %s err: %s", fileName, err)
}

l.filesMap[fileName] = string(data)
}
l.Started = true
return nil
}

func (l *LocalFileRenderer) RenderManifest(valsYaml string) (string, error) {
if !l.Started {
return "", errors.New("LocalFileRenderer has not been init")
}
keys := make([]string, 0, len(l.filesMap))
for key := range l.filesMap {
keys = append(keys, key)
}
// to ensure that every manifest rendered by same values are the same
sort.Strings(keys)

var builder strings.Builder
for i := 0; i < len(keys); i++ {
file := l.filesMap[keys[i]]
file = util.ApplyFilters(file, DefaultFilters...)
// ignore empty manifest
if file == "" {
continue
}
if !strings.HasSuffix(file, YAMLSeparator) {
file += YAMLSeparator
}
builder.WriteString(file)
}
return builder.String(), nil
}

func (l *LocalFileRenderer) SetVersion(version string) {
l.Opts.Version = version
}

// LocalChartRenderer load chart from local file system
type LocalChartRenderer struct {
Opts *RendererOptions
Chart *chart.Chart
Started bool
}

func (lr *LocalRenderer) Init() error {
func (lr *LocalChartRenderer) Init() error {
fileNames, err := getFileNames(lr.Opts.FS, lr.Opts.Dir)
if err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -212,18 +282,18 @@ func (lr *LocalRenderer) Init() error {
return nil
}

func (lr *LocalRenderer) RenderManifest(valsYaml string) (string, error) {
func (lr *LocalChartRenderer) RenderManifest(valsYaml string) (string, error) {
if !lr.Started {
return "", errors.New("LocalRenderer has not been init")
return "", errors.New("LocalChartRenderer has not been init")
}
return renderManifest(valsYaml, lr.Chart, true, lr.Opts, DefaultFilters...)
}

func (lr *LocalRenderer) SetVersion(version string) {
func (lr *LocalChartRenderer) SetVersion(version string) {
lr.Opts.Version = version
}

func NewLocalRenderer(opts ...RendererOption) (Renderer, error) {
func NewLocalChartRenderer(opts ...RendererOption) (Renderer, error) {
newOpts := &RendererOptions{}
for _, opt := range opts {
opt(newOpts)
Expand All @@ -232,7 +302,7 @@ func NewLocalRenderer(opts ...RendererOption) (Renderer, error) {
if err := verifyRendererOptions(newOpts); err != nil {
return nil, fmt.Errorf("verify err: %s", err)
}
return &LocalRenderer{
return &LocalChartRenderer{
Opts: newOpts,
}, nil
}
Expand Down
108 changes: 108 additions & 0 deletions pkg/cmd/hgctl/installer/gateway_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package installer

import (
"errors"
"fmt"
"io"
"strings"

"github.com/alibaba/higress/pkg/cmd/hgctl/helm"
"github.com/alibaba/higress/pkg/cmd/hgctl/manifests"
)

const (
GatewayAPI ComponentName = "gatewayAPI"
)

type GatewayAPIComponent struct {
profile *helm.Profile
started bool
opts *ComponentOptions
renderer helm.Renderer
writer io.Writer
}

func NewGatewayAPIComponent(profile *helm.Profile, writer io.Writer, opts ...ComponentOption) (Component, error) {
newOpts := &ComponentOptions{}
for _, opt := range opts {
opt(newOpts)
}

if !strings.HasPrefix(newOpts.RepoURL, "embed://") {
return nil, errors.New("GatewayAPI Url need start with embed://")
}

chartDir := strings.TrimPrefix(newOpts.RepoURL, "embed://")
// GatewayAPI can only be installed by embed type
renderer, err := helm.NewLocalFileRenderer(
helm.WithName(newOpts.ChartName),
helm.WithNamespace(newOpts.Namespace),
helm.WithRepoURL(newOpts.RepoURL),
helm.WithVersion(newOpts.Version),
helm.WithFS(manifests.BuiltinOrDir("")),
helm.WithDir(chartDir),
)
if err != nil {
return nil, err
}

gatewayAPIComponent := &GatewayAPIComponent{
profile: profile,
renderer: renderer,
opts: newOpts,
writer: writer,
}
return gatewayAPIComponent, nil
}

func (i *GatewayAPIComponent) ComponentName() ComponentName {
return GatewayAPI
}

func (i *GatewayAPIComponent) Namespace() string {
return i.opts.Namespace
}

func (i *GatewayAPIComponent) Enabled() bool {
return true
}

func (i *GatewayAPIComponent) Run() error {
if !i.opts.Quiet {
fmt.Fprintf(i.writer, "🏄 Downloading GatewayAPI Yaml Files version: %s, url: %s\n", i.opts.Version, i.opts.RepoURL)
}
if err := i.renderer.Init(); err != nil {
return err
}
i.started = true
return nil
}

func (i *GatewayAPIComponent) RenderManifest() (string, error) {
if !i.started {
return "", nil
}
if !i.opts.Quiet {
fmt.Fprintf(i.writer, "📦 Rendering GatewayAPI Yaml Files\n")
}
values := make(map[string]any)
manifest, err := renderComponentManifest(values, i.renderer, false, i.ComponentName(), i.opts.Namespace)
if err != nil {
return "", err
}
return manifest, nil
}
Loading

0 comments on commit 1e5dab2

Please sign in to comment.