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.
165 lines
5.1 KiB
Go
165 lines
5.1 KiB
Go
package node
|
|
|
|
import (
|
|
"github.com/hpcng/warewulf/internal/pkg/util"
|
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
|
)
|
|
|
|
/******
|
|
* YAML data representations
|
|
******/
|
|
|
|
type NodeYaml struct {
|
|
WWInternal int `yaml:"WW_INTERNAL"`
|
|
NodeProfiles map[string]*NodeConf
|
|
Nodes map[string]*NodeConf
|
|
}
|
|
|
|
/*
|
|
NodeConf is the datastructure which is stored on disk.
|
|
*/
|
|
type NodeConf struct {
|
|
Comment string `yaml:"comment,omitempty"`
|
|
ClusterName string `yaml:"cluster name,omitempty"`
|
|
ContainerName string `yaml:"container name,omitempty"`
|
|
Ipxe string `yaml:"ipxe template,omitempty"`
|
|
KernelVersion string `yaml:"kernel version,omitempty"`
|
|
KernelOverride string `yaml:"kernel override,omitempty"`
|
|
KernelArgs string `yaml:"kernel args,omitempty"`
|
|
IpmiUserName string `yaml:"ipmi username,omitempty"`
|
|
IpmiPassword string `yaml:"ipmi password,omitempty"`
|
|
IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"`
|
|
IpmiNetmask string `yaml:"ipmi netmask,omitempty"`
|
|
IpmiPort string `yaml:"ipmi port,omitempty"`
|
|
IpmiGateway string `yaml:"ipmi gateway,omitempty"`
|
|
IpmiInterface string `yaml:"ipmi interface,omitempty"`
|
|
IpmiWrite string `yaml:"ipmi write,omitempty"`
|
|
RuntimeOverlay []string `yaml:"runtime overlay,omitempty"`
|
|
SystemOverlay []string `yaml:"system overlay,omitempty"`
|
|
Kernel *KernelConf `yaml:"kernel,omitempty"`
|
|
Ipmi *IpmiConf `yaml:"ipmi,omitempty"`
|
|
Init string `yaml:"init,omitempty"`
|
|
Root string `yaml:"root,omitempty"`
|
|
AssetKey string `yaml:"asset key,omitempty"`
|
|
Discoverable string `yaml:"discoverable,omitempty"`
|
|
Profiles []string `yaml:"profiles,omitempty"`
|
|
NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"`
|
|
Tags map[string]string `yaml:"tags,omitempty"`
|
|
Keys map[string]string `yaml:"keys,omitempty"` // Reverse compatibility
|
|
}
|
|
|
|
type IpmiConf struct {
|
|
UserName string `yaml:"username,omitempty"`
|
|
Password string `yaml:"password,omitempty"`
|
|
Ipaddr string `yaml:"ipaddr,omitempty"`
|
|
Netmask string `yaml:"netmask,omitempty"`
|
|
Port string `yaml:"port,omitempty"`
|
|
Gateway string `yaml:"gateway,omitempty"`
|
|
Interface string `yaml:"interface,omitempty"`
|
|
Write string `yaml:"write,omitempty"`
|
|
}
|
|
type KernelConf struct {
|
|
Version string `yaml:"version,omitempty"`
|
|
Override string `yaml:"override,omitempty"`
|
|
Args string `yaml:"args,omitempty"`
|
|
}
|
|
|
|
type NetDevs struct {
|
|
Type string `yaml:"type,omitempty"`
|
|
OnBoot string `yaml:"onboot,omitempty"`
|
|
Device string `yaml:"device,omitempty"`
|
|
Hwaddr string `yaml:"hwaddr,omitempty"`
|
|
Ipaddr string `yaml:"ipaddr,omitempty"`
|
|
IpCIDR string `yaml:"ipcidr,omitempty"`
|
|
Ipaddr6 string `yaml:"ip6addr,omitempty"`
|
|
Prefix string `yaml:"prefix,omitempty"`
|
|
Netmask string `yaml:"netmask,omitempty"`
|
|
Gateway string `yaml:"gateway,omitempty"`
|
|
Primary string `yaml:"primary,omitempty"`
|
|
Default string `yaml:"default,omitempty"` /* backward compatibility */
|
|
Tags map[string]string `yaml:"tags,omitempty"`
|
|
}
|
|
|
|
/******
|
|
* Internal code data representations
|
|
******/
|
|
/*
|
|
Holds string values, when accessed via Get, its value
|
|
is returned which is the default or if set the value
|
|
from the profile or if set the value of the node itself
|
|
*/
|
|
type Entry struct {
|
|
value []string
|
|
altvalue []string
|
|
from string
|
|
def []string
|
|
}
|
|
|
|
/*
|
|
NodeInfo is the in memory datastructure, which can containe
|
|
a default value, which is overwritten by the overlay from the
|
|
overlay (altvalue) which is overwitten by the value of the
|
|
node itself, for all values of type Entry.
|
|
*/
|
|
type NodeInfo struct {
|
|
Id Entry
|
|
Cid Entry
|
|
Comment Entry
|
|
ClusterName Entry
|
|
ContainerName Entry
|
|
Ipxe Entry
|
|
RuntimeOverlay Entry
|
|
SystemOverlay Entry
|
|
Root Entry
|
|
Discoverable Entry
|
|
Init Entry //TODO: Finish adding this...
|
|
AssetKey Entry
|
|
Kernel *KernelEntry
|
|
Ipmi *IpmiEntry
|
|
Profiles []string
|
|
GroupProfiles []string
|
|
NetDevs map[string]*NetDevEntry
|
|
Tags map[string]*Entry
|
|
}
|
|
|
|
type IpmiEntry struct {
|
|
Ipaddr Entry
|
|
Netmask Entry
|
|
Port Entry
|
|
Gateway Entry
|
|
UserName Entry
|
|
Password Entry
|
|
Interface Entry
|
|
Write Entry
|
|
}
|
|
|
|
type KernelEntry struct {
|
|
Version Entry
|
|
Override Entry
|
|
Args Entry
|
|
}
|
|
|
|
type NetDevEntry struct {
|
|
Type Entry
|
|
OnBoot Entry
|
|
Device Entry
|
|
Hwaddr Entry
|
|
Ipaddr Entry
|
|
Ipaddr6 Entry
|
|
IpCIDR Entry
|
|
Prefix Entry
|
|
Netmask Entry
|
|
Gateway Entry
|
|
Primary Entry
|
|
Tags map[string]*Entry
|
|
}
|
|
|
|
func init() {
|
|
// Check that nodes.conf is found
|
|
if !util.IsFile(ConfigFile) {
|
|
wwlog.Printf(wwlog.WARN, "Missing node configuration file\n")
|
|
// just return silently, as init is also called for bash_completion
|
|
return
|
|
}
|
|
}
|