40
41
IPMI_DRIVER_CHOICES,
43
# FIXME: These should come from a hardware driver.
44
POWER_TYPE_PARAMETERS = {
45
# Empty type, for the case where nothing is entered in the form yet.
47
[], required=False, skip_check=True),
48
'ether_wake': DictCharField(
51
MACAddressFormField(label="MAC Address", required=False)),
55
'virsh': DictCharField(
58
forms.CharField(label="Address", required=False)),
60
forms.CharField(label="Power ID", required=False)),
64
'fence_cdu': DictCharField(
67
forms.CharField(label="Power ID", required=False)),
69
forms.CharField(label="IP Address or Hostname", required=False)),
71
forms.CharField(label="Username", required=False)),
73
forms.CharField(label="Password", required=False)),
77
'ipmi': DictCharField(
81
label="Driver", required=False,
82
choices=IPMI_DRIVER_CHOICES,
83
initial=IPMI_DRIVER.DEFAULT)),
85
forms.CharField(label="IP Address or Hostname", required=False)),
87
forms.CharField(label="Username", required=False)),
89
forms.CharField(label="Password", required=False)),
93
'moonshot': DictCharField(
97
label="IP Address or Hostname", required=False)),
99
forms.CharField(label="Username", required=False)),
101
forms.CharField(label="Password", required=False)),
103
forms.CharField(label="Hardware Address", required=False)),
107
'sm15k': DictCharField(
111
label="IP Address or Hostname", required=False)),
113
forms.CharField(label="Username", required=False)),
115
forms.CharField(label="Password", required=False)),
117
forms.CharField(label="System ID", required=False)),
121
'amt': DictCharField(
125
label="IP Address or Hostname", required=False)),
127
forms.CharField(label="Password", required=False)),
45
# Represent the Django choices format as JSON; an array of 2-item
47
CHOICE_FIELD_SCHEMA = {
50
'title': "Power type paramter field choice",
62
POWER_TYPE_PARAMETER_FIELD_SCHEMA = {
63
'title': "Power type parameter field",
78
'choices': CHOICE_FIELD_SCHEMA,
83
'required': ['field_type', 'label', 'required'],
87
# A basic JSON schema for what power type parameters should look like.
88
JSON_POWER_TYPE_PARAMETERS_SCHEMA = {
89
'title': "Power parameters set",
92
'title': "Power type parameters",
97
'items': POWER_TYPE_PARAMETER_FIELD_SCHEMA,
100
'required': ['fields'],
106
name, label, field_type=None, choices=None, default=None,
108
"""Helper function for building a JSON power type parameters field.
110
:param name: The name of the field.
112
:param label: The label to be presented to the user for this field.
114
:param field_type: The type of field to create. Can be one of
115
(string, choice, mac_address). Defaults to string.
116
:type field_type: string.
117
:param choices: The collection of choices to present to the user.
118
Needs to be structured as a list of lists, otherwise
119
make_json_field() will raise a ValidationError.
121
:param default: The default value for the field.
122
:type default: string
123
:param required: Whether or not a value for the field is required.
124
:type required: boolean
126
if field_type not in ('string', 'mac_address', 'choice'):
127
field_type = 'string'
130
validate(choices, CHOICE_FIELD_SCHEMA)
136
'required': required,
137
'field_type': field_type,
144
# FIXME this should all be produced by hardware drivers, not defined statically
146
JSON_POWER_TYPE_PARAMETERS = [
148
'name': 'ether_wake',
151
'mac_address', "MAC Address", field_type='mac_address'),
157
make_json_field('power_address', "Power address"),
158
make_json_field('power_id', "Power ID"),
164
make_json_field('power_address', "Power address"),
165
make_json_field('power_id', "Power ID"),
166
make_json_field('power_user', "Power user"),
167
make_json_field('power_pass', "Power password"),
174
'power_driver', "Power driver", field_type='choice',
175
choices=IPMI_DRIVER_CHOICES, default=IPMI_DRIVER.DEFAULT),
176
make_json_field('power_address', "Power address"),
177
make_json_field('power_user', "Power user"),
178
make_json_field('power_pass', "Power password"),
184
make_json_field('power_address', "Power address"),
185
make_json_field('power_user', "Power user"),
186
make_json_field('power_pass', "Power password"),
187
make_json_field('power_hwaddress', "Power hardware address"),
193
make_json_field('system_id', "System ID"),
194
make_json_field('power_address', "Power address"),
195
make_json_field('power_user', "Power user"),
196
make_json_field('power_pass', "Power password"),
203
'mac_address', "MAC Address", field_type='mac_address'),
204
make_json_field('power_pass', "Power password"),
210
FIELD_TYPE_MAPPINGS = {
211
'string': forms.CharField,
212
'mac_address': MACAddressFormField,
213
'choice': forms.ChoiceField,
217
def make_form_field(json_field):
218
"""Build a Django form field based on the JSON spec.
220
:param json_field: The JSON-specified field to convert into a valid
222
:type json_field: dict
223
:return: The correct Django form field for the field type, as
224
specified in FIELD_TYPE_MAPPINGS.
226
field_class = FIELD_TYPE_MAPPINGS.get(
227
json_field['field_type'], forms.CharField)
228
if json_field['field_type'] == 'choice':
230
'choices': json_field['choices'],
231
'initial': json_field['default'],
234
extra_parameters = {}
235
form_field = field_class(
236
label=json_field['label'], required=json_field['required'],
241
def get_power_type_parameters_from_json(json_power_type_parameters):
242
"""Return power type parameters.
244
:param json_power_type_parameters: Power type parameters expressed
245
as a JSON string or as set of JSONSchema-verifiable objects.
246
Will be validated using jsonschema.validate().
247
:type json_power_type_parameters: JSON string or iterable.
248
:return: A dict of power parameters for all power types, indexed by
251
validate(json_power_type_parameters, JSON_POWER_TYPE_PARAMETERS_SCHEMA)
253
# Empty type, for the case where nothing is entered in the form yet.
255
[], required=False, skip_check=True),
257
for power_type in json_power_type_parameters:
259
for json_field in power_type['fields']:
261
json_field['name'], make_form_field(json_field)))
262
params = DictCharField(fields, required=False, skip_check=True)
263
power_parameters[power_type['name']] = params
264
return power_parameters
267
# We do this once because there's no point re-parsing the JSON every
268
# time we need to look up the power type parameters code.
269
POWER_TYPE_PARAMETERS = get_power_type_parameters_from_json(
270
JSON_POWER_TYPE_PARAMETERS)