Skip to content

Commit

Permalink
support the provisioner_engine metadata value (#135)
Browse files Browse the repository at this point in the history
## Description

Boots should check the provisioiner_engine metadata value against the PROVISIONER_ENGINE_NAME runtime environment to decide if it should be handling DHCP requests for a given piece of hardware.

## Why is this needed

To allow for multiple differing versions of boots to be running in an environment, with DHCP relayed to both simultaneously to aid in blue/green deployment testing.
  • Loading branch information
mergify[bot] authored Mar 17, 2021
2 parents b8320d5 + 89e8f57 commit ad742e1
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 19 deletions.
14 changes: 14 additions & 0 deletions job/dhcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ func IsSpecialOS(i *packet.Instance) bool {
// ServeDHCP responds to DHCP packets
func (j Job) ServeDHCP(w dhcp4.ReplyWriter, req *dhcp4.Packet) bool {

// If we are not the chosen provisioner for this piece of hardware
// do not respond to the DHCP request
if !j.areWeProvisioner() {
return false
}

// setup reply
reply := dhcp.NewReply(w, req)
if reply == nil {
Expand Down Expand Up @@ -83,6 +89,14 @@ func (j Job) isPXEAllowed() bool {
return j.instance.AllowPXE
}

func (j Job) areWeProvisioner() bool {
if j.hardware.HardwareProvisioner() == "" {
return true
}

return j.hardware.HardwareProvisioner() == j.ProvisionerEngineName()
}

func (j Job) setPXEFilename(rep *dhcp4.Packet, isPacket, isARM, isUEFI bool) {
if j.HardwareState() == "in_use" {
if j.InstanceID() == "" {
Expand Down
28 changes: 28 additions & 0 deletions job/dhcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,34 @@ func TestAllowPXE(t *testing.T) {
}
}

func TestAreWeProvisioner(t *testing.T) {
for _, tt := range []struct {
want bool
ProvisionerEngine string
env string
}{
{want: true, ProvisionerEngine: "tinkerbell", env: "tinkerbell"},
{want: false, ProvisionerEngine: "tinkerbell", env: "packet"},
{want: true, ProvisionerEngine: "", env: "packet"},
{want: false, ProvisionerEngine: "tinkerbell", env: ""},
} {
t.Logf("want=%t, ProvisionerEngine=%s env=%s",
tt.want, tt.ProvisionerEngine, tt.env)
j := Job{
hardware: &packet.HardwareTinkerbellV1{
Metadata: packet.Metadata{
ProvisionerEngine: tt.ProvisionerEngine,
},
},
}
SetProvisionerEngineName(tt.env)
got := j.areWeProvisioner()
if got != tt.want {
t.Fatalf("unexpected return, want: %t, got %t", tt.want, got)
}
}
}

func TestIsSpecialOS(t *testing.T) {
t.Run("nil instance", func(t *testing.T) {
special := IsSpecialOS(nil)
Expand Down
13 changes: 13 additions & 0 deletions job/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,19 @@ import (
)

var client *packet.Client
var provisionerEngineName string

// SetClient sets the client used to interact with the api.
func SetClient(c *packet.Client) {
client = c
}

// SetProvisionerEngineName sets the provisioning engine name used
// for this instance of boots
func SetProvisionerEngineName(engineName string) {
provisionerEngineName = engineName
}

// Job this comment is useless
type Job struct {
log.Logger
Expand All @@ -42,6 +49,12 @@ func (j Job) AllowPxe() bool {
return j.hardware.HardwareAllowPXE(j.mac)
}

// ProvisionerEngineName returns the current provisioning engine name
// as defined by the env var PROVISIONER_ENGINE_NAME supplied at runtime
func (j Job) ProvisionerEngineName() string {
return provisionerEngineName
}

// HasActiveWorkflow fetches workflows for the given hardware and returns
// the status true if there is a pending (active) workflow
func HasActiveWorkflow(hwID packet.HardwareID) (bool, error) {
Expand Down
6 changes: 4 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ import (
)

var (
client *packet.Client
apiBaseURL = env.URL("API_BASE_URL", "https://api.packet.net")
client *packet.Client
apiBaseURL = env.URL("API_BASE_URL", "https://api.packet.net")
provisionerEngineName = env.Get("PROVISIONER_ENGINE_NAME", "packet")

mainlog log.Logger

Expand Down Expand Up @@ -73,6 +74,7 @@ func main() {
mainlog.Fatal(err)
}
job.SetClient(client)
job.SetProvisionerEngineName(provisionerEngineName)

go func() {
mainlog.Info("serving syslog")
Expand Down
4 changes: 3 additions & 1 deletion packet/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type Hardware interface {
HardwareIPs() []IP
Interfaces() []Port // TODO: to be updated
HardwareManufacturer() string
HardwareProvisioner() string
HardwarePlanSlug() string
HardwarePlanVersionSlug() string
HardwareState() HardwareState
Expand Down Expand Up @@ -296,7 +297,8 @@ type Metadata struct {
PreinstalledOS OperatingSystem `json:"preinstalled_operating_system_version"`
PrivateSubnets []string `json:"private_subnets"`
} `json:"custom"`
Facility Facility `json:"facility"`
Facility Facility `json:"facility"`
ProvisionerEngine string `json:"provisioner_engine"`
}

// Facility represents the facilty in use
Expand Down
37 changes: 21 additions & 16 deletions packet/models_cacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,23 @@ type HardwareCacher struct {
Name string `json:"name"`
State HardwareState `json:"state"`

BondingMode BondingMode `json:"bonding_mode"`
NetworkPorts []Port `json:"network_ports"`
Manufacturer Manufacturer `json:"manufacturer"`
PlanSlug string `json:"plan_slug"`
PlanVersionSlug string `json:"plan_version_slug"`
Arch string `json:"arch"`
FacilityCode string `json:"facility_code"`
IPMI IP `json:"management"`
IPs []IP `json:"ip_addresses"`
PreinstallOS OperatingSystem `json:"preinstalled_operating_system_version"`
PrivateSubnets []string `json:"private_subnets,omitempty"`
UEFI bool `json:"efi_boot"`
AllowPXE bool `json:"allow_pxe"`
AllowWorkflow bool `json:"allow_workflow"`
ServicesVersion ServicesVersion `json:"services"`
Instance *Instance `json:"instance"`
BondingMode BondingMode `json:"bonding_mode"`
NetworkPorts []Port `json:"network_ports"`
Manufacturer Manufacturer `json:"manufacturer"`
PlanSlug string `json:"plan_slug"`
PlanVersionSlug string `json:"plan_version_slug"`
Arch string `json:"arch"`
FacilityCode string `json:"facility_code"`
IPMI IP `json:"management"`
IPs []IP `json:"ip_addresses"`
PreinstallOS OperatingSystem `json:"preinstalled_operating_system_version"`
PrivateSubnets []string `json:"private_subnets,omitempty"`
UEFI bool `json:"efi_boot"`
AllowPXE bool `json:"allow_pxe"`
AllowWorkflow bool `json:"allow_workflow"`
ServicesVersion ServicesVersion `json:"services"`
Instance *Instance `json:"instance"`
ProvisionerEngine string `json:"provisioner_engine"`
}

func (d DiscoveryCacher) Hardware() Hardware {
Expand Down Expand Up @@ -308,6 +309,10 @@ func (h HardwareCacher) HardwareManufacturer() string {
return h.Manufacturer.Slug
}

func (h HardwareCacher) HardwareProvisioner() string {
return h.ProvisionerEngine
}

func (h HardwareCacher) HardwarePlanSlug() string {
return h.PlanSlug
}
Expand Down
4 changes: 4 additions & 0 deletions packet/models_tinkerbell.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ func (h HardwareTinkerbellV1) HardwareIPs() []IP {
// return h.DHCP.IP // is this correct?
//}

func (h HardwareTinkerbellV1) HardwareProvisioner() string {
return h.Metadata.ProvisionerEngine
}

func (h HardwareTinkerbellV1) HardwareManufacturer() string {
return h.Metadata.Manufacturer.Slug
}
Expand Down

0 comments on commit ad742e1

Please sign in to comment.