github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/internal/fs/client/discover.templ (about)

     1  // generated code; DO NOT EDIT
     2  
     3  package {{ .Package }}
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/choria-io/go-choria/client/discovery"
    12  	"github.com/choria-io/go-choria/providers/discovery/broadcast"
    13  	"github.com/choria-io/go-choria/providers/discovery/external"
    14  	"github.com/choria-io/go-choria/providers/discovery/puppetdb"
    15  	"github.com/choria-io/go-choria/protocol"
    16  	"github.com/choria-io/go-choria/inter"
    17  )
    18  
    19  // BroadcastNS is a NodeSource that uses the Choria network broadcast method to discover nodes
    20  type BroadcastNS struct {
    21  	nodeCache []string
    22  	f         *protocol.Filter
    23  
    24  	sync.Mutex
    25  }
    26  
    27  // Reset resets the internal node cache
    28  func (b *BroadcastNS) Reset() {
    29  	b.Lock()
    30  	defer b.Unlock()
    31  
    32  	b.nodeCache = []string{}
    33  }
    34  
    35  // Discover performs the discovery of nodes against the Choria Network
    36  func (b *BroadcastNS) Discover(ctx context.Context, fw inter.Framework, filters []FilterFunc) ([]string, error) {
    37  	b.Lock()
    38  	defer b.Unlock()
    39  
    40  	copier := func() []string {
    41  		out := make([]string, len(b.nodeCache))
    42  		copy(out, b.nodeCache)
    43  
    44  		return out
    45  	}
    46  
    47  	if !(b.nodeCache == nil || len(b.nodeCache) == 0) {
    48  		return copier(), nil
    49  	}
    50  
    51  	var err error
    52  
    53  	b.f, err = parseFilters(filters)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	if b.nodeCache == nil {
    59  		b.nodeCache = []string{}
    60  	}
    61  
    62  	cfg := fw.Configuration()
    63  	nodes, err := broadcast.New(fw).Discover(ctx, broadcast.Filter(b.f), broadcast.Timeout(time.Second*time.Duration(cfg.DiscoveryTimeout)))
    64  	if err != nil {
    65  		return []string{}, err
    66  	}
    67  
    68  	b.nodeCache = nodes
    69  
    70  	return copier(), nil
    71  }
    72  
    73  // ExternalNS is a NodeSource that calls an external command for discovery
    74  type ExternalNS struct {
    75  	nodeCache []string
    76  	f         *protocol.Filter
    77  
    78  	sync.Mutex
    79  }
    80  
    81  // Reset resets the internal node cache
    82  func (p *ExternalNS) Reset() {
    83  	p.Lock()
    84  	defer p.Unlock()
    85  
    86  	p.nodeCache = []string{}
    87  }
    88  
    89  func (p *ExternalNS) Discover(ctx context.Context, fw inter.Framework, filters []FilterFunc) ([]string, error) {
    90  	p.Lock()
    91  	defer p.Unlock()
    92  
    93  	copier := func() []string {
    94  		out := make([]string, len(p.nodeCache))
    95  		copy(out, p.nodeCache)
    96  
    97  		return out
    98  	}
    99  
   100  	if !(p.nodeCache == nil || len(p.nodeCache) == 0) {
   101  		return copier(), nil
   102  	}
   103  
   104  	var err error
   105  	p.f, err = parseFilters(filters)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	if p.nodeCache == nil {
   111  		p.nodeCache = []string{}
   112  	}
   113  
   114  	cfg := fw.Configuration()
   115  	nodes, err := external.New(fw).Discover(ctx, external.Filter(p.f), external.Timeout(time.Second*time.Duration(cfg.DiscoveryTimeout)))
   116  	if err != nil {
   117  		return []string{}, err
   118  	}
   119  
   120  	p.nodeCache = nodes
   121  
   122  	return copier(), nil
   123  }
   124  
   125  // PuppetDBNS is a NodeSource that uses the PuppetDB PQL Queries to discover nodes
   126  type PuppetDBNS struct {
   127  	nodeCache []string
   128  	f         *protocol.Filter
   129  
   130  	sync.Mutex
   131  }
   132  
   133  // Reset resets the internal node cache
   134  func (p *PuppetDBNS) Reset() {
   135  	p.Lock()
   136  	defer p.Unlock()
   137  
   138  	p.nodeCache = []string{}
   139  }
   140  
   141  // Discover performs the discovery of nodes against the Choria Network
   142  func (p *PuppetDBNS) Discover(ctx context.Context, fw inter.Framework, filters []FilterFunc) ([]string, error) {
   143  	p.Lock()
   144  	defer p.Unlock()
   145  
   146  	copier := func() []string {
   147  		out := make([]string, len(p.nodeCache))
   148  		copy(out, p.nodeCache)
   149  
   150  		return out
   151  	}
   152  
   153  	if !(p.nodeCache == nil || len(p.nodeCache) == 0) {
   154  		return copier(), nil
   155  	}
   156  
   157  	var err error
   158  	p.f, err = parseFilters(filters)
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	if len(p.f.Compound) > 0 {
   164  		return nil, fmt.Errorf("compound filters are not supported by PuppetDB")
   165  	}
   166  
   167  	if p.nodeCache == nil {
   168  		p.nodeCache = []string{}
   169  	}
   170  
   171  	cfg := fw.Configuration()
   172  	nodes, err := puppetdb.New(fw).Discover(ctx, puppetdb.Filter(p.f), puppetdb.Timeout(time.Second*time.Duration(cfg.DiscoveryTimeout)))
   173  	if err != nil {
   174  		return []string{}, err
   175  	}
   176  
   177  	p.nodeCache = nodes
   178  
   179  	return copier(), nil
   180  }
   181  
   182  // MetaNS is a NodeSource that assists CLI tools in creating Choria standard command line based discovery.
   183  type MetaNS struct {
   184  	// Options is the CLI options to discover based on
   185  	Options *discovery.StandardOptions
   186  
   187  	// Agent should be the agent the request is targeted at
   188  	Agent string
   189  
   190  	// DisablePipedDiscovery prevents the STDIN being used as a discovery source
   191  	DisablePipedDiscovery bool
   192  
   193  	nodeCache []string
   194  	sync.Mutex
   195  }
   196  
   197  // NewMetaNS creates a new meta discovery node source
   198  func NewMetaNS(opts *discovery.StandardOptions, enablePipeMode bool) *MetaNS {
   199  	return &MetaNS{
   200  		Options:               opts,
   201  		Agent:                 "{{ .DDL.Metadata.Name }}",
   202  		DisablePipedDiscovery: !enablePipeMode,
   203  		nodeCache:             []string{},
   204  	}
   205  }
   206  
   207  // Reset resets the internal node cache
   208  func (p *MetaNS) Reset() {
   209  	p.Lock()
   210  	defer p.Unlock()
   211  
   212  	p.nodeCache = []string{}
   213  }
   214  
   215  // Discover performs the discovery of nodes against the Choria Network.
   216  func (p *MetaNS) Discover(ctx context.Context, fw inter.Framework, _ []FilterFunc) ([]string, error) {
   217  	p.Lock()
   218  	defer p.Unlock()
   219  
   220  	copier := func() []string {
   221  		out := make([]string, len(p.nodeCache))
   222  		copy(out, p.nodeCache)
   223  
   224  		return out
   225  	}
   226  
   227  	if !(p.nodeCache == nil || len(p.nodeCache) == 0) {
   228  		return copier(), nil
   229  	}
   230  
   231  	if p.nodeCache == nil {
   232  		p.nodeCache = []string{}
   233  	}
   234  
   235  	if p.Options == nil {
   236  		return nil, fmt.Errorf("options have not been set")
   237  	}
   238  
   239  	nodes, _, err := p.Options.Discover(ctx, fw, p.Agent, !p.DisablePipedDiscovery, false, fw.Logger("discovery"))
   240  	if err != nil {
   241  		return nil, err
   242  	}
   243  
   244  	p.nodeCache = nodes
   245  
   246  	return copier(), nil
   247  }
   248  
   249  func parseFilters(fs []FilterFunc) (*protocol.Filter, error) {
   250  	filter := protocol.NewFilter()
   251  
   252  	for _, f := range fs {
   253  		err := f(filter)
   254  		if err != nil {
   255  			return nil, err
   256  		}
   257  	}
   258  
   259  	return filter, nil
   260  }