github.com/netdata/go.d.plugin@v0.58.1/modules/openvpn/openvpn.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package openvpn
     4  
     5  import (
     6  	_ "embed"
     7  	"time"
     8  
     9  	"github.com/netdata/go.d.plugin/modules/openvpn/client"
    10  	"github.com/netdata/go.d.plugin/pkg/matcher"
    11  	"github.com/netdata/go.d.plugin/pkg/socket"
    12  	"github.com/netdata/go.d.plugin/pkg/web"
    13  
    14  	"github.com/netdata/go.d.plugin/agent/module"
    15  )
    16  
    17  const (
    18  	defaultAddress        = "127.0.0.1:7505"
    19  	defaultConnectTimeout = time.Second * 2
    20  	defaultReadTimeout    = time.Second * 2
    21  	defaultWriteTimeout   = time.Second * 2
    22  )
    23  
    24  //go:embed "config_schema.json"
    25  var configSchema string
    26  
    27  func init() {
    28  	module.Register("openvpn", module.Creator{
    29  		JobConfigSchema: configSchema,
    30  		Defaults: module.Defaults{
    31  			Disabled: true,
    32  		},
    33  		Create: func() module.Module { return New() },
    34  	})
    35  }
    36  
    37  // New creates OpenVPN with default values.
    38  func New() *OpenVPN {
    39  	config := Config{
    40  		Address:        defaultAddress,
    41  		ConnectTimeout: web.Duration{Duration: defaultConnectTimeout},
    42  		ReadTimeout:    web.Duration{Duration: defaultReadTimeout},
    43  		WriteTimeout:   web.Duration{Duration: defaultWriteTimeout},
    44  	}
    45  	return &OpenVPN{
    46  		Config:         config,
    47  		charts:         charts.Copy(),
    48  		collectedUsers: make(map[string]bool),
    49  	}
    50  }
    51  
    52  // Config is the OpenVPN module configuration.
    53  type Config struct {
    54  	Address        string
    55  	ConnectTimeout web.Duration       `yaml:"connect_timeout"`
    56  	ReadTimeout    web.Duration       `yaml:"read_timeout"`
    57  	WriteTimeout   web.Duration       `yaml:"write_timeout"`
    58  	PerUserStats   matcher.SimpleExpr `yaml:"per_user_stats"`
    59  }
    60  
    61  type openVPNClient interface {
    62  	socket.Client
    63  	Version() (*client.Version, error)
    64  	LoadStats() (*client.LoadStats, error)
    65  	Users() (client.Users, error)
    66  }
    67  
    68  // OpenVPN OpenVPN module.
    69  type OpenVPN struct {
    70  	module.Base
    71  	Config         `yaml:",inline"`
    72  	client         openVPNClient
    73  	charts         *Charts
    74  	collectedUsers map[string]bool
    75  	perUserMatcher matcher.Matcher
    76  }
    77  
    78  // Cleanup makes cleanup.
    79  func (o *OpenVPN) Cleanup() {
    80  	if o.client == nil {
    81  		return
    82  	}
    83  	_ = o.client.Disconnect()
    84  }
    85  
    86  // Init makes initialization.
    87  func (o *OpenVPN) Init() bool {
    88  	if !o.PerUserStats.Empty() {
    89  		m, err := o.PerUserStats.Parse()
    90  		if err != nil {
    91  			o.Errorf("error on creating per user stats matcher : %v", err)
    92  			return false
    93  		}
    94  		o.perUserMatcher = matcher.WithCache(m)
    95  	}
    96  
    97  	config := socket.Config{
    98  		Address:        o.Address,
    99  		ConnectTimeout: o.ConnectTimeout.Duration,
   100  		ReadTimeout:    o.ReadTimeout.Duration,
   101  		WriteTimeout:   o.WriteTimeout.Duration,
   102  	}
   103  	o.client = &client.Client{Client: socket.New(config)}
   104  
   105  	o.Infof("using address: %s, connect timeout: %s, read timeout: %s, write timeout: %s",
   106  		o.Address, o.ConnectTimeout.Duration, o.ReadTimeout.Duration, o.WriteTimeout.Duration)
   107  
   108  	return true
   109  }
   110  
   111  // Check makes check.
   112  func (o *OpenVPN) Check() bool {
   113  	if err := o.client.Connect(); err != nil {
   114  		o.Error(err)
   115  		return false
   116  	}
   117  	defer func() { _ = o.client.Disconnect() }()
   118  
   119  	ver, err := o.client.Version()
   120  	if err != nil {
   121  		o.Error(err)
   122  		o.Cleanup()
   123  		return false
   124  	}
   125  
   126  	o.Infof("connected to OpenVPN v%d.%d.%d, Management v%d", ver.Major, ver.Minor, ver.Patch, ver.Management)
   127  	return true
   128  }
   129  
   130  // Charts creates Charts.
   131  func (o OpenVPN) Charts() *Charts { return o.charts }
   132  
   133  // Collect collects metrics.
   134  func (o *OpenVPN) Collect() map[string]int64 {
   135  	mx, err := o.collect()
   136  	if err != nil {
   137  		o.Error(err)
   138  	}
   139  
   140  	if len(mx) == 0 {
   141  		return nil
   142  	}
   143  	return mx
   144  }