Skip to content

Commit

Permalink
Create port for node when node exists and has no port allocated.
Browse files Browse the repository at this point in the history
Signed-off-by: s3rj1k <evasive.gyron@gmail.com>
  • Loading branch information
s3rj1k committed May 3, 2021
1 parent 2e6cac3 commit c45ecfb
Showing 1 changed file with 96 additions and 11 deletions.
107 changes: 96 additions & 11 deletions pkg/provisioner/ironic/ironic.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,53 @@ func (p *ironicProvisioner) getNode() (*nodes.Node, error) {
}
}

// Verifies that node has port assigned by Ironic.
func (p *ironicProvisioner) nodeHasAssignedPort(ironicNode *nodes.Node) (bool, error) {
opts := ports.ListOpts{
Fields: []string{"node_uuid"},
NodeUUID: ironicNode.UUID,
}

pager := ports.List(p.client, opts)
if pager.Err != nil {
return false, errors.Wrap(pager.Err, "failed to list ports")
}

allPages, err := pager.AllPages()
if err != nil {
return false, errors.Wrap(err, "failed to page over list of ports")
}

empty, err := allPages.IsEmpty()
if err != nil {
return false, errors.Wrap(err, "failed to check port list status")
}

if empty {
p.debugLog.Info("node has no assigned port")
return false, nil
}

p.debugLog.Info("node has assigned port")
return true, nil
}

// Verify that MAC is already allocated to some node port.
func (p *ironicProvisioner) isAddressAllocatedToPort(address string) (bool, error) {
allPorts, err := p.listAllPorts(address)
if err != nil {
return false, errors.Wrap(err, fmt.Sprintf("failed to list ports for %s", address))
}

if len(allPorts) == 0 {
p.debugLog.Info("address does not have allocated ports", "address", address)
return false, nil
}

p.debugLog.Info("address is allocated to port", "address", address)
return true, nil
}

// Look for an existing registration for the host in Ironic.
func (p *ironicProvisioner) findExistingHost(bootMACAddress string) (ironicNode *nodes.Node, err error) {
// Try to load the node by UUID
Expand Down Expand Up @@ -389,6 +436,25 @@ func (p *ironicProvisioner) findExistingHost(bootMACAddress string) (ironicNode
return nil, nil
}

func (p *ironicProvisioner) createPXEEnabledNodePort(uuid, macAddress string) error {
p.log.Info("creating PXE enabled ironic port for node", "NodeUUID", uuid, "MAC", macAddress)

enable := true

_, err := ports.Create(
p.client,
ports.CreateOpts{
NodeUUID: uuid,
Address: macAddress,
PXEEnabled: &enable,
}).Extract()
if err != nil {
return errors.Wrap(err, fmt.Sprintf("failed to create ironic port for node: %s, MAC: %s", uuid, macAddress))
}

return nil
}

// ValidateManagementAccess registers the host with the provisioning
// system and tests the connection information for the host to verify
// that the location and credentials work.
Expand Down Expand Up @@ -475,18 +541,9 @@ func (p *ironicProvisioner) ValidateManagementAccess(data provisioner.Management
// If we know the MAC, create a port. Otherwise we will have
// to do this after we run the introspection step.
if p.bootMACAddress != "" {
enable := true
p.log.Info("creating port for node in ironic", "MAC",
p.bootMACAddress)
_, err = ports.Create(
p.client,
ports.CreateOpts{
NodeUUID: ironicNode.UUID,
Address: p.bootMACAddress,
PXEEnabled: &enable,
}).Extract()
err = p.createPXEEnabledNodePort(ironicNode.UUID, p.bootMACAddress)
if err != nil {
result, err = transientError(errors.Wrap(err, "failed to create port in ironic"))
result, err = transientError(err)
return
}
}
Expand All @@ -499,6 +556,34 @@ func (p *ironicProvisioner) ValidateManagementAccess(data provisioner.Management

updater.SetTopLevelOpt("name", ironicNodeName(p.objectMeta), ironicNode.Name)

// When node exists but has no assigned port to it by Ironic and actuall address (MAC) is present
// in host config and is not allocated to different node lets try to create port for this node.
if p.bootMACAddress != "" {
var nodeHasAssignedPort, addressIsAllocatedToPort bool

nodeHasAssignedPort, err = p.nodeHasAssignedPort(ironicNode)
if err != nil {
result, err = transientError(err)
return
}

if !nodeHasAssignedPort {
addressIsAllocatedToPort, err = p.isAddressAllocatedToPort(p.bootMACAddress)
if err != nil {
result, err = transientError(err)
return
}

if !addressIsAllocatedToPort {
err = p.createPXEEnabledNodePort(ironicNode.UUID, p.bootMACAddress)
if err != nil {
result, err = transientError(err)
return
}
}
}
}

// Look for the case where we previously enrolled this node
// and now the credentials have changed.
if credentialsChanged {
Expand Down

0 comments on commit c45ecfb

Please sign in to comment.