go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ipfixplugin/descriptor/flowprobe_params.go (about)

     1  // Copyright (c) 2020 Cisco and/or its affiliates.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at:
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package descriptor
    16  
    17  import (
    18  	"errors"
    19  
    20  	"go.ligato.io/cn-infra/v2/idxmap"
    21  	"go.ligato.io/cn-infra/v2/logging"
    22  
    23  	kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api"
    24  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/descriptor/adapter"
    25  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls"
    26  	ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix"
    27  )
    28  
    29  const (
    30  	// FPParamsDescriptorName is the name of the descriptor for
    31  	// VPP Flowprobe Params configuration.
    32  	FPParamsDescriptorName = "vpp-flowprobe-params"
    33  )
    34  
    35  var (
    36  	// Validation errors:
    37  
    38  	// ErrAllRecordFieldsDisabled returned when all record fields are set to false.
    39  	ErrAllRecordFieldsDisabled = errors.New("at least one of record fields (l2, l3, l4) must be set")
    40  
    41  	// Non-retriable errors:
    42  
    43  	// ErrFeatureEnabled informs the reason why Flowprobe Params can not be changed.
    44  	ErrFeatureEnabled = errors.New("can not change Flowprobe Params when Flowprobe Feature enabled on some interface")
    45  )
    46  
    47  // FPParamsDescriptor configures Flowprobe Params for VPP.
    48  type FPParamsDescriptor struct {
    49  	ipfixHandler vppcalls.IpfixVppAPI
    50  	featureMap   idxmap.NamedMapping
    51  	log          logging.Logger
    52  }
    53  
    54  // NewFPParamsDescriptor creates a new instance of FPParamsDescriptor.
    55  func NewFPParamsDescriptor(ipfixHandler vppcalls.IpfixVppAPI, featureMap idxmap.NamedMapping, log logging.PluginLogger) *kvs.KVDescriptor {
    56  	ctx := &FPParamsDescriptor{
    57  		ipfixHandler: ipfixHandler,
    58  		featureMap:   featureMap,
    59  		log:          log.NewLogger("flowprobe-params-descriptor"),
    60  	}
    61  	typedDescr := &adapter.FlowProbeParamsDescriptor{
    62  		Name:               FPParamsDescriptorName,
    63  		NBKeyPrefix:        ipfix.ModelFlowprobeParams.KeyPrefix(),
    64  		ValueTypeName:      ipfix.ModelFlowprobeParams.ProtoName(),
    65  		KeySelector:        ipfix.ModelFlowprobeParams.IsKeyValid,
    66  		KeyLabel:           ipfix.ModelFlowprobeParams.StripKeyPrefix,
    67  		IsRetriableFailure: ctx.IsRetriableFailure,
    68  		Validate:           ctx.Validate,
    69  		Create:             ctx.Create,
    70  		Delete:             ctx.Delete,
    71  		Update:             ctx.Update,
    72  		Retrieve:           ctx.Retrieve,
    73  	}
    74  	return adapter.NewFlowProbeParamsDescriptor(typedDescr)
    75  }
    76  
    77  // Validate checks if Flowprobe Params are good to send to VPP.
    78  func (d *FPParamsDescriptor) Validate(key string, value *ipfix.FlowProbeParams) error {
    79  	if !(value.GetRecordL2() || value.GetRecordL3() || value.GetRecordL4()) {
    80  		return kvs.NewInvalidValueError(ErrAllRecordFieldsDisabled,
    81  			"record_l2", "record_l3", "record_l4")
    82  	}
    83  
    84  	return nil
    85  }
    86  
    87  // IsRetriableFailure returns false if error is one of errors
    88  // defined at the top of this file as non-retriable.
    89  func (d *FPParamsDescriptor) IsRetriableFailure(err error) bool {
    90  	return !errors.Is(err, ErrFeatureEnabled)
    91  }
    92  
    93  // Create passes Flowprobe Params to Update method.
    94  func (d *FPParamsDescriptor) Create(key string, val *ipfix.FlowProbeParams) (metadata interface{}, err error) {
    95  	_, err = d.Update(key, nil, val, nil)
    96  	return
    97  }
    98  
    99  // Update uses vppcalls to pass Flowprobe Params to VPP.
   100  func (d *FPParamsDescriptor) Update(key string, oldVal, newVal *ipfix.FlowProbeParams, oldMetadata interface{}) (newMetadata interface{}, err error) {
   101  	// Check if there is at least one Flowporbe Feature configured on some interface.
   102  	if len(d.featureMap.ListAllNames()) > 0 {
   103  		err = ErrFeatureEnabled
   104  		return
   105  	}
   106  	err = d.ipfixHandler.SetFPParams(newVal)
   107  	return
   108  }
   109  
   110  // Delete does nothing.
   111  //
   112  // Since all Flowprobe Features are dependent on Flowprobe Params,
   113  // calling this method will also disable (move to "pending" state)
   114  // all Flowprobe Features on interfaces.
   115  //
   116  // All the work will be done by KVScheduler :)
   117  func (d *FPParamsDescriptor) Delete(key string, val *ipfix.FlowProbeParams, metadata interface{}) (err error) {
   118  	return
   119  }
   120  
   121  // Retrieve hopes that configuration in correlate is actual configuration in VPP.
   122  // As soon as VPP devs will add dump API calls, this methods should be fixed.
   123  func (d *FPParamsDescriptor) Retrieve(correlate []adapter.FlowProbeParamsKVWithMetadata) (retrieved []adapter.FlowProbeParamsKVWithMetadata, err error) {
   124  	return correlate, nil
   125  }