CLI Apply Chassis Types

Chassis types appear in a dropdown when creating or editing chassis records via the web ui. For new deployments with known equipment, the CLI makes it possible to seed this data from files.

Chassis Types Dropdown

Curate your assets

Using a directory managed by version control such as git, lay out a directory structure containing YAML or JSON assets. Any depth of folder hierarchy is supported.

my-assets/
  bitscope/
    blades/
      CB04B.yaml
    rackmounts/
      ER08A.yaml
  uctronics/
    rackmounts/
      U6258.json

The JSON layout of a chassis type can be scraped via the web browser's JavaScript console, or this example can be used:

# my-chassis-types/bitscope/blades/CB04B.yaml
id: c0lrpqun8s3m99789sgg
kind: ChassisType
manufacturer: BitScope
model: Cluster Blade
partNumber: CB04B
type: Blade
url: "http://my.bitscope.com/store/?p=view&i=product+CB04B"
capabilities:
  deviceCapacity: 4

Importing

Leave off the --dry-run flag to perform an actual import.

$ onprem apply --dry-run ./my-chassis-types

Writing a lambda to augmenting Redfish ComputerSystem info with BitScope Station IDs

Alongside the chassis definition, you might also want to define lambdas specific to the hardware. This example shows how the On Prem platform defines the lambda that performs Station ID discovery for nodes mounted on a BitScope Cluster Blade.

The lambda is triggered by the On Prem Service Broker Toolkit trigger event clq6t05uc97j94h99c4g, which is invoked whenever the On Prem Agent is asked by the control plane to provide the Redfish ComputerSystem info for the current node. Operators are free to define their own custom Lamba Triggers; this just happens to be one that is built into the agent and available to all deployments.

Directory structure:

my-chassis-types/
  BitScope/
    blades/
      cb04b/
        cb04b.yaml
        cb04b.jpg
        bitscope_cb04b_collect_redfish_computer_system.lua
        bitscope_cb04b_collect_redfish_computer_system.yaml
$ onprem generate xid
clq7735uc97jteljcm70
# collect_redfish_computer_system.yaml
id: clq7735uc97jteljcm70
kind: Lambda
triggerType: clq6t05uc97j94h99c4g
name: bitscope_cb04b_collect_redfish_computer_system
description: >
  When a BMC is present, such as when a device is mounted on a CB04B Cluster Blade, collect
  the station ID and other details into the Redfish Oem field.
runAt:
  allDevices: true
scriptContentType: text/x-lua
script: "@bitscope_cb04b_collect_redfish_computer_system.lua"
-- bitscope_cb04b_collect_redfish_computer_system.lua
local Serial = require('periphery').Serial
local M = {}

local function parse_status_line(line)
  local words = {}
  for word in line:gmatch('[^%s]+') do
    words[#words + 1] = word
  end
  assert(#words == 5)
  local id = tonumber(words[1], 16)
  local ms = tonumber(words[2], 16)
  local pwr = tonumber(words[3], 16)
  local cur = tonumber(words[4], 16)
  local fan = tonumber(words[5], 16)
  return id, ms, pwr, cur, fan
end

local function readline(serial, maxLength, timeout)
  local line = ''
  for i = 1, maxLength + 1 do
    local c = serial:read(1, timeout)
    if c == nil or c == '\n' then
      break
    end
    line = line .. c
  end
  return line
end

local function write_command(serial, command, timeout_ms)
  for i = 1, #command do
    local c = command:sub(i, i)
    serial:write(c)
    assert(serial:read(1, timeout_ms) == c)
  end
end

local function get_status(serial, timeout_ms)
  write_command(serial, '=', timeout_ms)
  assert(serial:read(1, timeout_ms) == '\n')
  local line = readline(serial, 14, timeout_ms)
  return parse_status_line(line)
end

local function get_uuid(serial, timeout_ms)
  write_command(serial, '#', timeout_ms)
  assert(serial:read(1, timeout_ms) == '\n')
  local uuid = readline(serial, 36, timeout_ms)
  assert(#uuid == 36)
  return uuid
end

local function collect(serial, timeout_ms, event)
  -- Populate oem['bitscope.com'] field
  local oem = event['oem']
  if oem == nil then
    oem = {}
    event['oem'] = oem
  end
  local oem_bitscope = oem['bitscope.com']
  if oem_bitscope == nil then
    oem_bitscope = {}
    oem['bitscope.com'] = oem_bitscope
  end

  -- Populate oem['bitscope.com']['station'] field
  local id, _, _, _, _ = get_status(serial, timeout_ms)
  oem_bitscope['station'] = id

  -- Populate oem['bitscope.com']['uuid'] field
  oem_bitscope['uuid'] = get_uuid(serial, timeout_ms)

  return event
end

function M.handler(event, context)
  local device = '/dev/serial0'
  local f = io.open(device, 'r')
  if f ~= nil then
    local serial = Serial(device, 115200)
    event = collect(serial, 50, event)
  end
  return event
end

return M

The end result a Redfish record augmented with Oem info specific to the hardware:

Console