github.com/kubevela/workflow@v0.6.0/pkg/providers/util/util.go (about)

     1  /*
     2   Copyright 2022. The KubeVela Authors.
     3  
     4   Licensed under the Apache License, Version 2.0 (the "License");
     5   you may not use this file except in compliance with the License.
     6   You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10   Unless required by applicable law or agreed to in writing, software
    11   distributed under the License is distributed on an "AS IS" BASIS,
    12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   See the License for the specific language governing permissions and
    14   limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  
    23  	monitorContext "github.com/kubevela/pkg/monitor/context"
    24  
    25  	wfContext "github.com/kubevela/workflow/pkg/context"
    26  	"github.com/kubevela/workflow/pkg/cue/model"
    27  	"github.com/kubevela/workflow/pkg/cue/model/value"
    28  	"github.com/kubevela/workflow/pkg/cue/process"
    29  	"github.com/kubevela/workflow/pkg/types"
    30  )
    31  
    32  const (
    33  	// ProviderName is provider name for install.
    34  	ProviderName = "util"
    35  )
    36  
    37  type provider struct {
    38  	pCtx process.Context
    39  }
    40  
    41  func (p *provider) PatchK8sObject(ctx monitorContext.Context, wfCtx wfContext.Context, v *value.Value, act types.Action) error {
    42  	val, err := v.LookupValue("value")
    43  	if err != nil {
    44  		return err
    45  	}
    46  	pv, err := v.LookupValue("patch")
    47  	if err != nil {
    48  		return err
    49  	}
    50  	base, err := model.NewBase(val.CueValue())
    51  	if err != nil {
    52  		return err
    53  	}
    54  	if err = base.Unify(pv.CueValue()); err != nil {
    55  		return v.FillObject(err, "err")
    56  	}
    57  
    58  	workload, err := base.Unstructured()
    59  	if err != nil {
    60  		return v.FillObject(err, "err")
    61  	}
    62  	return v.FillObject(workload.Object, "result")
    63  }
    64  
    65  // String convert byte to string
    66  func (p *provider) String(ctx monitorContext.Context, wfCtx wfContext.Context, v *value.Value, act types.Action) error {
    67  	b, err := v.LookupValue("bt")
    68  	if err != nil {
    69  		return err
    70  	}
    71  	s, err := b.CueValue().Bytes()
    72  	if err != nil {
    73  		return err
    74  	}
    75  	return v.FillObject(string(s), "str")
    76  }
    77  
    78  // Log print cue value in log
    79  func (p *provider) Log(ctx monitorContext.Context, wfCtx wfContext.Context, v *value.Value, act types.Action) error {
    80  	stepName := fmt.Sprint(p.pCtx.GetData(model.ContextStepName))
    81  	stepID := fmt.Sprint(p.pCtx.GetData(model.ContextStepSessionID))
    82  	config := make(map[string]types.LogConfig)
    83  	c := wfCtx.GetMutableValue(types.ContextKeyLogConfig)
    84  	if c != "" {
    85  		if err := json.Unmarshal([]byte(c), &config); err != nil {
    86  			return err
    87  		}
    88  	}
    89  	stepConfig := config[stepName]
    90  	data, err := v.LookupValue("data")
    91  	if err == nil {
    92  		level := 3
    93  		logLevel, err := v.LookupValue("level")
    94  		if err == nil {
    95  			l, err := logLevel.CueValue().Int64()
    96  			if err == nil {
    97  				level = int(l)
    98  			}
    99  		}
   100  		if err := printDataInLog(ctx, data, level, stepID, &stepConfig); err != nil {
   101  			return err
   102  		}
   103  	}
   104  	source, err := v.LookupValue("source")
   105  	if err == nil {
   106  		if err := setSourceInLog(source, &stepConfig); err != nil {
   107  			return err
   108  		}
   109  	}
   110  	config[stepName] = stepConfig
   111  	b, err := json.Marshal(config)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	wfCtx.SetMutableValue(string(b), types.ContextKeyLogConfig)
   116  	return nil
   117  }
   118  
   119  func printDataInLog(ctx monitorContext.Context, data *value.Value, level int, stepID string, stepConfig *types.LogConfig) error {
   120  	stepConfig.Data = true
   121  	logCtx := ctx.Fork("cue logs")
   122  	logCtx.AddTag(model.ContextStepSessionID, stepID)
   123  	logCtx.V(level)
   124  	if s, err := data.GetString(); err == nil {
   125  		logCtx.Info(s)
   126  		return nil
   127  	}
   128  	var tmp interface{}
   129  	if err := data.UnmarshalTo(&tmp); err != nil {
   130  		return err
   131  	}
   132  	b, err := json.Marshal(tmp)
   133  	if err != nil {
   134  		return err
   135  	}
   136  	logCtx.Info(string(b))
   137  	return nil
   138  }
   139  
   140  func setSourceInLog(source *value.Value, stepConfig *types.LogConfig) error {
   141  	if stepConfig.Source == nil {
   142  		stepConfig.Source = &types.LogSource{}
   143  	}
   144  	if v, err := source.LookupValue("url"); err == nil {
   145  		url, err := v.GetString()
   146  		if err != nil {
   147  			return err
   148  		}
   149  		stepConfig.Source.URL = url
   150  	}
   151  	if v, err := source.LookupValue("resources"); err == nil {
   152  		b, err := v.CueValue().MarshalJSON()
   153  		if err != nil {
   154  			return err
   155  		}
   156  		resources := []types.Resource{}
   157  		if err := json.Unmarshal(b, &resources); err != nil {
   158  			return err
   159  		}
   160  		stepConfig.Source.Resources = resources
   161  	}
   162  	return nil
   163  }
   164  
   165  // Install register handlers to provider discover.
   166  func Install(p types.Providers, pCtx process.Context) {
   167  	prd := &provider{
   168  		pCtx: pCtx,
   169  	}
   170  	p.Register(ProviderName, map[string]types.Handler{
   171  		"patch-k8s-object": prd.PatchK8sObject,
   172  		"string":           prd.String,
   173  		"log":              prd.Log,
   174  	})
   175  }