blob: 43087eb35a9c89a2a93aeaea7ace95dfd8247c83 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 kube
import (
"errors"
"fmt"
)
import (
"github.com/apache/dubbo-kubernetes/app/dubboctl/identifier"
"github.com/apache/dubbo-kubernetes/app/dubboctl/internal/apis/dubbo.apache.org/v1alpha1"
"github.com/apache/dubbo-kubernetes/pkg/core/logger"
)
type DubboOperator struct {
spec *v1alpha1.DubboConfigSpec
started bool
components map[ComponentName]Component
kubeCli *CtlClient
}
// Run must be invoked before invoking other functions.
func (do *DubboOperator) Run() error {
for name, component := range do.components {
if err := component.Run(); err != nil {
return fmt.Errorf("bootstrap %s run failed, err: %s", name, err)
}
}
do.started = true
return nil
}
// RenderManifest renders bootstrap manifests specified by DubboConfigSpec.
func (do *DubboOperator) RenderManifest() (map[ComponentName]string, error) {
if !do.started {
return nil, errors.New("DubboOperator is not running")
}
res := make(map[ComponentName]string)
for name, component := range do.components {
manifest, err := component.RenderManifest()
if err != nil {
return nil, fmt.Errorf("bootstrap %s RenderManifest err: %v", name, err)
}
res[name] = manifest
}
return res, nil
}
// ApplyManifest apply bootstrap manifests to k8s cluster
func (do *DubboOperator) ApplyManifest(manifestMap map[ComponentName]string) error {
if do.kubeCli == nil {
return errors.New("no injected k8s cli into DubboOperator")
}
for name, manifest := range manifestMap {
logger.CmdSugar().Infof("Start applying bootstrap %s\n", name)
if err := do.kubeCli.ApplyManifest(manifest, do.spec.Namespace, name); err != nil {
return fmt.Errorf("bootstrap %s ApplyManifest err: %v", name, err)
}
logger.CmdSugar().Infof("Applying bootstrap %s successfully\n", name)
}
return nil
}
// RemoveManifest removes resources represented by bootstrap manifests
func (do *DubboOperator) RemoveManifest(manifestMap map[ComponentName]string) error {
if do.kubeCli == nil {
return errors.New("no injected k8s cli into DubboOperator")
}
for name, manifest := range manifestMap {
logger.CmdSugar().Infof("Start removing bootstrap %s\n", name)
if err := do.kubeCli.RemoveManifest(manifest, do.spec.Namespace); err != nil {
return fmt.Errorf("bootstrap %s RemoveManifest err: %v", name, err)
}
logger.CmdSugar().Infof("Removing bootstrap %s successfully\n", name)
}
return nil
}
// NewDubboOperator accepts cli directly for testing and normal use.
// For now, every related command needs a dedicated DubboOperator.
func NewDubboOperator(spec *v1alpha1.DubboConfigSpec, cli *CtlClient) (*DubboOperator, error) {
if spec == nil {
return nil, errors.New("DubboConfigSpec is empty")
}
ns := spec.Namespace
if ns == "" {
ns = identifier.DubboSystemNamespace
}
// initialize components
components := make(map[ComponentName]Component)
if spec.IsAdminEnabled() {
admin, err := NewAdminComponent(spec.Components.Admin,
WithNamespace(ns),
WithChartPath(spec.ChartPath),
)
if err != nil {
return nil, fmt.Errorf("NewAdminComponent failed, err: %s", err)
}
components[Admin] = admin
}
if spec.IsGrafanaEnabled() {
grafana, err := NewGrafanaComponent(spec.Components.Grafana,
WithNamespace(ns),
WithChartPath(spec.ChartPath),
WithRepoURL(spec.ComponentsMeta.Grafana.RepoURL),
WithVersion(spec.ComponentsMeta.Grafana.Version),
)
if err != nil {
return nil, fmt.Errorf("NewGrafanaComponent failed, err: %s", err)
}
components[Grafana] = grafana
}
if spec.IsNacosEnabled() {
nacos, err := NewNacosComponent(spec.Components.Nacos,
WithNamespace(ns),
WithChartPath(spec.ChartPath),
)
if err != nil {
return nil, fmt.Errorf("NewNacosComponent failed, err: %s", err)
}
components[Nacos] = nacos
}
if spec.IsZookeeperEnabled() {
zookeeper, err := NewZookeeperComponent(spec.Components.Zookeeper,
WithNamespace(ns),
WithChartPath(spec.ChartPath),
WithRepoURL(spec.ComponentsMeta.Zookeeper.RepoURL),
WithVersion(spec.ComponentsMeta.Zookeeper.Version),
)
if err != nil {
return nil, fmt.Errorf("NewZookeeperComponent failed, err: %s", err)
}
components[Zookeeper] = zookeeper
}
if spec.IsPrometheusEnabled() {
prometheus, err := NewPrometheusComponent(spec.Components.Prometheus,
WithNamespace(ns),
WithChartPath(spec.ChartPath),
WithRepoURL(spec.ComponentsMeta.Prometheus.RepoURL),
WithVersion(spec.ComponentsMeta.Prometheus.Version),
)
if err != nil {
return nil, fmt.Errorf("NewPrometheusComponent failed, err: %s", err)
}
components[Prometheus] = prometheus
}
if spec.IsSkywalkingEnabled() {
skywalking, err := NewSkywalkingComponent(spec.Components.Skywalking,
WithNamespace(ns),
WithChartPath(spec.ChartPath),
WithRepoURL(spec.ComponentsMeta.Skywalking.RepoURL),
WithVersion(spec.ComponentsMeta.Skywalking.Version),
)
if err != nil {
return nil, fmt.Errorf("NewSkywalkingComponent failed, err: %s", err)
}
components[Skywalking] = skywalking
}
if spec.IsZipkinEnabled() {
zipkin, err := NewZipkinComponent(spec.Components.Zipkin,
WithNamespace(ns),
WithChartPath(spec.ChartPath),
WithRepoURL(spec.ComponentsMeta.Zipkin.RepoURL),
WithVersion(spec.ComponentsMeta.Zipkin.Version),
)
if err != nil {
return nil, fmt.Errorf("NewZipkinComponent failed, err: %s", err)
}
components[Zipkin] = zipkin
}
do := &DubboOperator{
spec: spec,
components: components,
kubeCli: cli,
}
return do, nil
}