blob: 2d1b72dcf0f2be7a04bced3c26aad1425b243ccb [file] [log] [blame]
// Licensed to 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. Apache Software Foundation (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 manifest
import (
"bufio"
"fmt"
"io"
"os"
"strings"
"github.com/apache/skywalking-swck/pkg/kubernetes"
"github.com/apache/skywalking-swck/pkg/operator/repo"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/runtime"
)
var Command = &cli.Command{
Name: "manifest",
Aliases: []string{"mf"},
Usage: "Output the Kubernetes manifest for installing OAP server and UI to stdout",
Subcommands: []*cli.Command{
oapCmd,
uiCmd,
},
}
var flags = []cli.Flag{
&cli.StringFlag{
Name: "name",
Usage: "The name of prefix of generated resources",
Required: false,
Value: "skywalking",
},
&cli.StringFlag{
Name: "namespace",
Usage: "The namespace where resource will be deployed",
Required: false,
Value: "skywalking-system",
},
&cli.StringFlag{
Name: "f",
Usage: "The custom resource file describing custom resources defined by swck",
Required: false,
},
}
func usage(command, exampleOverlays string) string {
return fmt.Sprintf(`
Examples:
%s
1. Output manifest with default custom resource
$ swctl install manifest %s
2. Load overlay custom resource from flag
$ swctl install manifest %s -f %s-cr.yaml
3. Load overlay custom resource from stdin
$ cat %s-cr.yaml | swctl install manifest %s -f=-
4. Apply directly to Kubernetes
$ swctl install manifest %s -f %s-cr.yaml | kubectl apply -f-
`, exampleOverlays, command, command, command, command, command, command, command)
}
func loadOverlay(file string, in io.Reader, out interface{}) error {
if file == "" {
return nil
}
if file == "-" {
scanner := bufio.NewScanner(in)
ll := make([]string, 0)
for scanner.Scan() {
ll = append(ll, scanner.Text())
}
if len(ll) > 0 {
if err := yaml.Unmarshal([]byte(strings.Join(ll, "\n")), out); err != nil {
return err
}
}
} else {
b, err := os.ReadFile(file)
if err != nil {
return err
}
if err := yaml.Unmarshal(b, out); err != nil {
return err
}
}
return nil
}
func render(repoName string, ctx *cli.Context, base, overlay runtime.Object) error {
if ctx.String("f") != "" {
if err := applyOverlay(ctx, base, overlay); err != nil {
return err
}
}
r := repo.NewRepo(repoName)
ff, err := r.GetFilesRecursive("templates")
if err != nil {
return fmt.Errorf("failed to load resource templates: %v", err)
}
for _, f := range ff {
manifests, err := r.ReadFile(f)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to read template file content: %v", err)
continue
}
bb, err := kubernetes.GenerateManifests(string(manifests), base, nil)
if err != nil && err != kubernetes.ErrNothingLoaded {
fmt.Fprintf(os.Stderr, "failed to generate manifest: %v", err)
continue
}
fmt.Println(string(bb))
fmt.Println("---")
}
return nil
}
func applyOverlay(ctx *cli.Context, base, overlay runtime.Object) error {
if err := loadOverlay(ctx.String("f"), os.Stdin, overlay); err != nil {
return fmt.Errorf("falied to load overlay from flag -f: %v", err)
}
if err := kubernetes.ApplyOverlay(base, overlay); err != nil {
return fmt.Errorf("failed to apply overlay to base: %v", err)
}
return nil
}