Files
kubevela/references/cli/logs.go
qiaozp 23cbc9c91f Feat: implement pipeline APIs (#4908)
* add context when run pipeline

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Feat: implement pipeline API

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Extract get log logic and implement getPipelineRunLog API

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Init and delete pipeline contexts

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix panic

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Allow not specifying context

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* change pipeline to path parameter

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Add permission check filter

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* project -> projects in route

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix route conflict

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Add project alias

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Feat: change the list pipeline API

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: filter the project

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: the error of the run APi

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* fix log pipeline run API

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix lint, fix the error of log api

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix error returning

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: change the lable to annotation

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* remove log config not found error

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix pipeline list api return no context info

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: create the namespace

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* get pipeline lastrun info

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* allow query single step output

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* organize code in api layer

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix project filter, add context value when get pp run, extend lastRun

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix get output and implement get input api

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: change the last run

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* if query sub-step outout, return it directly

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: change the run stats

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: change the output

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* flatten the input/output api

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* more info for i/o vars

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix nested i/o struct

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add fromStep in input api

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add e2e test skeleton

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add more e2e test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* use db to store pipeline

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* keep the last 5k lines of log

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* use stern param to keep last lines of logs

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* filter, nil labels, spec check

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* empty res, index, detail param

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Add e2e test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix e2e test and unit test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add context e2e test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* goimports

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add more test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* review

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* remove optional tag in returned value, unify the imports name

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix e2e test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add stop test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* more coverage

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* single case selct

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* optimize log color

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add default permission and role

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix permission ut

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* change the log api implementation

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add color, add container order

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* lint

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix filter nil will cut all log

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* longer timeout and lint

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-10-31 23:59:04 +08:00

178 lines
4.6 KiB
Go

/*
Copyright 2021 The KubeVela Authors.
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 cli
import (
"context"
"fmt"
"strings"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/util"
querytypes "github.com/oam-dev/kubevela/pkg/velaql/providers/query/types"
"github.com/oam-dev/kubevela/references/appfile"
)
// NewLogsCommand creates `logs` command to tail logs of application
func NewLogsCommand(c common.Args, order string, ioStreams util.IOStreams) *cobra.Command {
largs := &Args{Args: c}
cmd := &cobra.Command{
Use: "logs APP_NAME",
Short: "Tail logs for application.",
Long: "Tail logs for vela application.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var err error
largs.Namespace, err = GetFlagNamespaceOrEnv(cmd, c)
if err != nil {
return err
}
largs.Name = args[0]
ctx := context.Background()
app, err := appfile.LoadApplication(largs.Namespace, args[0], c)
if err != nil {
return err
}
largs.App = app
if err := largs.Run(ctx, ioStreams); err != nil {
return err
}
return nil
},
Annotations: map[string]string{
types.TagCommandOrder: order,
types.TagCommandType: types.TypeApp,
},
}
cmd.Flags().StringVarP(&largs.Output, "output", "o", "default", "output format for logs, support: [default, raw, json]")
cmd.Flags().StringVarP(&largs.ComponentName, "component", "c", "", "filter the pod by the component name")
cmd.Flags().StringVarP(&largs.ClusterName, "cluster", "", "", "filter the pod by the cluster name")
cmd.Flags().StringVarP(&largs.PodName, "pod", "p", "", "specify the pod name")
cmd.Flags().StringVarP(&largs.ContainerName, "container", "", "", "specify the container name")
addNamespaceAndEnvArg(cmd)
return cmd
}
// Args creates arguments for `logs` command
type Args struct {
Output string
Args common.Args
Name string
CtxName string
Namespace string
ContainerName string
PodName string
ClusterName string
ComponentName string
StepName string
App *v1beta1.Application
}
func (l *Args) printPodLogs(ctx context.Context, ioStreams util.IOStreams, selectPod *querytypes.PodBase, filters []string) error {
config, err := l.Args.GetConfig()
if err != nil {
return err
}
logC := make(chan string, 1024)
var t string
switch l.Output {
case "default":
if color.NoColor {
t = "{{.ContainerName}} {{.Message}}"
} else {
t = "{{color .ContainerColor .ContainerName}} {{.Message}}"
}
case "raw":
t = "{{.Message}}"
case "json":
t = "{{json .}}\n"
}
go func() {
for {
select {
case str := <-logC:
show := true
for _, filter := range filters {
if !strings.Contains(str, filter) {
show = false
break
}
}
if show {
ioStreams.Infonln(str)
}
case <-ctx.Done():
return
}
}
}()
err = utils.GetPodsLogs(ctx, config, l.ContainerName, []*querytypes.PodBase{selectPod}, t, logC, nil)
if err != nil {
return err
}
return nil
}
// Run refer to the implementation at https://github.com/oam-dev/stern/blob/master/stern/main.go
func (l *Args) Run(ctx context.Context, ioStreams util.IOStreams) error {
pods, err := GetApplicationPods(ctx, l.App.Name, l.App.Namespace, l.Args, Filter{
Component: l.ComponentName,
Cluster: l.ClusterName,
})
if err != nil {
return err
}
var selectPod *querytypes.PodBase
if l.PodName != "" {
for i, pod := range pods {
if pod.Metadata.Name == l.PodName {
selectPod = &pods[i]
break
}
}
if selectPod == nil {
fmt.Println("The Pod you specified does not exist, please select it from the list.")
}
}
if selectPod == nil {
selectPod, err = AskToChooseOnePod(pods)
if err != nil {
return err
}
}
if selectPod == nil {
return nil
}
if selectPod.Cluster != "" {
ctx = multicluster.ContextWithClusterName(ctx, selectPod.Cluster)
}
return l.printPodLogs(ctx, ioStreams, selectPod, nil)
}