Initial cut of wwapi.
We need an API for Warewulf in order to automate around it. The initial version of the API will look a lot like wwctl. wwctl will call the API so that we do not need to maintain separate code paths. In this preview wwctl calls the API via direct function call, but we can change that to a gprc or REST call to a Warewulf server in the future.
This commit contains:
wwapid WareWulf API Daemon. A grpc server with mTLS auth.
wwapic WareWulf API Client. A grpc client with mTLS auth. It's just a sample that reads the version from the server.
wwapird WareWulf API Rest Daemon. A http REST reverse proxy to wwapid.
There are also sample insecure and secure curls to test with.
Implemented Functionality:
wwctl node add
wwctl node delete
wwctl node list
wwctl node set
wwctl node status
wwctl container build
wwctl container delete
wwctl container import
wwctl container list
wwctl container show
Some notes on the files:
Logic that was in wwctl has moved to warewulf/internal/pkg/api. wwctl just calls the API. wwctl functionality is unchanged.
Everything under the /google directory is copied google proto code to stand up wwapird. It's a bit strange to copy in the code, but that is currently how it's done.
Everything in warewulf/internal/pkg/api/routes/wwapiv1 is generated code.
There are some loose ends here, such as no service installers. I just ran off the command line for development.
The Makefile could use improvement. I'm building by make clean setup proto all build wwapid wwapic wwapird ; echo $?
I copied the configs from warewulf/etc to /usr/local/etc/warewulf manually.
This commit is contained in:
@@ -24,8 +24,8 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func New() (nodeYaml, error) {
|
||||
var ret nodeYaml
|
||||
func New() (NodeYaml, error) {
|
||||
var ret NodeYaml
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Opening node configuration file: %s\n", ConfigFile)
|
||||
data, err := ioutil.ReadFile(ConfigFile)
|
||||
@@ -49,7 +49,7 @@ Get all the nodes of a configuration. This function also merges
|
||||
the nodes with the given profiles and set the default values
|
||||
for every node
|
||||
*/
|
||||
func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
wwconfig, err := warewulfconf.New()
|
||||
if err != nil {
|
||||
@@ -180,7 +180,14 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
}
|
||||
n.NetDevs[devname].Tags[keyname].Set(key)
|
||||
}
|
||||
|
||||
n.NetDevs[devname].Tags = make(map[string]*Entry)
|
||||
for keyname, key := range netdev.Tags {
|
||||
if _, ok := n.Tags[keyname]; !ok {
|
||||
var keyVar Entry
|
||||
n.NetDevs[devname].Tags[keyname] = &keyVar
|
||||
}
|
||||
n.NetDevs[devname].Tags[keyname].Set(key)
|
||||
}
|
||||
}
|
||||
|
||||
// Merge Keys into Tags for backwards compatibility
|
||||
@@ -302,7 +309,7 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (config *nodeYaml) FindAllProfiles() ([]NodeInfo, error) {
|
||||
func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
for name, profile := range config.NodeProfiles {
|
||||
@@ -434,7 +441,7 @@ func (config *nodeYaml) FindAllProfiles() ([]NodeInfo, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (config *nodeYaml) FindDiscoverableNode() (NodeInfo, string, error) {
|
||||
func (config *NodeYaml) FindDiscoverableNode() (NodeInfo, string, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
nodes, _ := config.FindAllNodes()
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
* YAML data representations
|
||||
******/
|
||||
|
||||
type nodeYaml struct {
|
||||
type NodeYaml struct {
|
||||
WWInternal int `yaml:"WW_INTERNAL"`
|
||||
NodeProfiles map[string]*NodeConf
|
||||
Nodes map[string]*NodeConf
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
*
|
||||
****/
|
||||
|
||||
func (config *nodeYaml) AddNode(nodeID string) (NodeInfo, error) {
|
||||
func (config *NodeYaml) AddNode(nodeID string) (NodeInfo, error) {
|
||||
var node NodeConf
|
||||
var n NodeInfo
|
||||
|
||||
@@ -37,7 +37,7 @@ func (config *nodeYaml) AddNode(nodeID string) (NodeInfo, error) {
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (config *nodeYaml) DelNode(nodeID string) error {
|
||||
func (config *NodeYaml) DelNode(nodeID string) error {
|
||||
|
||||
if _, ok := config.Nodes[nodeID]; !ok {
|
||||
return errors.New("Nodename does not exist: " + nodeID)
|
||||
@@ -49,7 +49,7 @@ func (config *nodeYaml) DelNode(nodeID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (config *nodeYaml) NodeUpdate(node NodeInfo) error {
|
||||
func (config *NodeYaml) NodeUpdate(node NodeInfo) error {
|
||||
nodeID := node.Id.Get()
|
||||
|
||||
if _, ok := config.Nodes[nodeID]; !ok {
|
||||
@@ -126,7 +126,7 @@ func (config *nodeYaml) NodeUpdate(node NodeInfo) error {
|
||||
*
|
||||
****/
|
||||
|
||||
func (config *nodeYaml) AddProfile(profileID string) (NodeInfo, error) {
|
||||
func (config *NodeYaml) AddProfile(profileID string) (NodeInfo, error) {
|
||||
var node NodeConf
|
||||
var n NodeInfo
|
||||
|
||||
@@ -143,7 +143,7 @@ func (config *nodeYaml) AddProfile(profileID string) (NodeInfo, error) {
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (config *nodeYaml) DelProfile(profileID string) error {
|
||||
func (config *NodeYaml) DelProfile(profileID string) error {
|
||||
|
||||
if _, ok := config.NodeProfiles[profileID]; !ok {
|
||||
return errors.New("Profile does not exist: " + profileID)
|
||||
@@ -158,7 +158,7 @@ func (config *nodeYaml) DelProfile(profileID string) error {
|
||||
/*
|
||||
Update the the config for the given profile so that it can unmarshalled.
|
||||
*/
|
||||
func (config *nodeYaml) ProfileUpdate(profile NodeInfo) error {
|
||||
func (config *NodeYaml) ProfileUpdate(profile NodeInfo) error {
|
||||
profileID := profile.Id.Get()
|
||||
|
||||
if _, ok := config.NodeProfiles[profileID]; !ok {
|
||||
@@ -228,7 +228,7 @@ func (config *nodeYaml) ProfileUpdate(profile NodeInfo) error {
|
||||
*
|
||||
****/
|
||||
|
||||
func (config *nodeYaml) Persist() error {
|
||||
func (config *NodeYaml) Persist() error {
|
||||
|
||||
out, err := yaml.Marshal(config)
|
||||
if err != nil {
|
||||
|
||||
@@ -25,7 +25,7 @@ nodes:
|
||||
hwaddr: 08:00:27:39:46:70
|
||||
ipaddr: 10.0.8.150
|
||||
`
|
||||
var nodeYaml nodeYaml
|
||||
var nodeYaml NodeYaml
|
||||
err := yaml.Unmarshal([]byte(nodeConfig), &nodeYaml)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (config *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
func (config *NodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
if _, err := net.ParseMAC(hwa); err != nil {
|
||||
return NodeInfo{}, errors.New("invalid hardware address: " + hwa)
|
||||
}
|
||||
@@ -26,7 +26,7 @@ func (config *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
return ret, errors.New("No nodes found with HW Addr: " + hwa)
|
||||
}
|
||||
|
||||
func (config *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) {
|
||||
func (config *NodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) {
|
||||
if net.ParseIP(ipaddr) == nil {
|
||||
return NodeInfo{}, errors.New("invalid IP:" + ipaddr)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func NewTestNode() (nodeYaml, error) {
|
||||
func NewTestNode() (NodeYaml, error) {
|
||||
var data = `
|
||||
nodeprofiles:
|
||||
default:
|
||||
@@ -39,7 +39,7 @@ nodes:
|
||||
default: false
|
||||
ipaddr: fd1a:2b3c:4d5e:06f0:1234:5678:90ab:cdef
|
||||
`
|
||||
var ret nodeYaml
|
||||
var ret NodeYaml
|
||||
err := yaml.Unmarshal([]byte(data), &ret)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
@@ -59,7 +59,7 @@ func Test_nodeYaml_FindByHwaddr(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
//fields fields
|
||||
config nodeYaml
|
||||
config NodeYaml
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
@@ -95,7 +95,7 @@ func Test_nodeYaml_FindByIpaddr(t *testing.T) {
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
config nodeYaml
|
||||
config NodeYaml
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
|
||||
Reference in New Issue
Block a user