github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/providers/discovery/inventory/datafile.go (about)

     1  // Copyright (c) 2021, R.I. Pienaar and the Choria Project contributors
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package inventory
     6  
     7  import (
     8  	"encoding/json"
     9  
    10  	"github.com/choria-io/go-choria/filter/facts"
    11  	"github.com/choria-io/go-choria/protocol"
    12  )
    13  
    14  // DataSchema the schema of supported inventory files
    15  const DataSchema = "https://choria.io/schemas/choria/discovery/v1/inventory_file.json"
    16  
    17  // DataFile is a source for discovery information that describes a fleet
    18  type DataFile struct {
    19  	Schema string  `json:"$schema" yaml:"$schema"`
    20  	Groups []Group `json:"groups,omitempty" yaml:"groups,omitempty"`
    21  	Nodes  []Node  `json:"nodes" yaml:"nodes"`
    22  }
    23  
    24  type GroupFilter struct {
    25  	Agents     []string `json:"agents,omitempty" yaml:"agents,omitempty"`
    26  	Classes    []string `json:"classes,omitempty" yaml:"classes,omitempty"`
    27  	Facts      []string `json:"facts,omitempty" yaml:"facts,omitempty"`
    28  	Identities []string `json:"identities,omitempty" yaml:"identities,omitempty"`
    29  	Compound   string   `json:"compound,omitempty" yaml:"compound,omitempty"`
    30  }
    31  
    32  func (f *GroupFilter) ToProtocolFilter() (*protocol.Filter, error) {
    33  	filter := protocol.NewFilter()
    34  
    35  	if f == nil {
    36  		return filter, nil
    37  	}
    38  
    39  	for _, fact := range f.Facts {
    40  		ff, err := facts.ParseFactFilterString(fact)
    41  		if err != nil {
    42  			return nil, err
    43  		}
    44  
    45  		err = filter.AddFactFilter(ff[0], ff[1], ff[2])
    46  		if err != nil {
    47  			return nil, err
    48  		}
    49  	}
    50  
    51  	for _, agent := range f.Agents {
    52  		filter.AddAgentFilter(agent)
    53  	}
    54  
    55  	for _, id := range f.Identities {
    56  		filter.AddIdentityFilter(id)
    57  	}
    58  
    59  	for _, c := range f.Classes {
    60  		filter.AddClassFilter(c)
    61  	}
    62  
    63  	if f.Compound != "" {
    64  		err := filter.AddCompoundFilter(f.Compound)
    65  		if err != nil {
    66  			return nil, err
    67  		}
    68  	}
    69  
    70  	return filter, nil
    71  }
    72  
    73  // Group is a view over the inventory expressed as a filter saved by name
    74  type Group struct {
    75  	Name   string       `json:"name" yaml:"name"`
    76  	Filter *GroupFilter `json:"filter,omitempty" yaml:"filter,omitempty"`
    77  }
    78  
    79  // Node describes a single node on the network
    80  type Node struct {
    81  	Name        string          `json:"name" yaml:"name"`
    82  	Collectives []string        `json:"collectives" yaml:"collectives"`
    83  	Facts       json.RawMessage `json:"facts" yaml:"facts"`
    84  	Classes     []string        `json:"classes" yaml:"classes"`
    85  	Agents      []string        `json:"agents" yaml:"agents"`
    86  }
    87  
    88  // LookupGroup finds a group by name
    89  func (d *DataFile) LookupGroup(name string) (*Group, bool) {
    90  	for _, g := range d.Groups {
    91  		if g.Name == name {
    92  			return &g, true
    93  		}
    94  	}
    95  
    96  	return nil, false
    97  }