Coverage for nova/notifications/objects/instance.py: 98%

332 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-17 15:08 +0000

1# Licensed under the Apache License, Version 2.0 (the "License"); you may 

2# not use this file except in compliance with the License. You may obtain 

3# a copy of the License at 

4# 

5# http://www.apache.org/licenses/LICENSE-2.0 

6# 

7# Unless required by applicable law or agreed to in writing, software 

8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

10# License for the specific language governing permissions and limitations 

11# under the License. 

12 

13import nova.conf 

14from nova.notifications.objects import base 

15from nova.notifications.objects import flavor as flavor_payload 

16from nova.notifications.objects import keypair as keypair_payload 

17from nova.objects import base as nova_base 

18from nova.objects import fields 

19 

20 

21CONF = nova.conf.CONF 

22 

23 

24@nova_base.NovaObjectRegistry.register_notification 

25class InstancePayload(base.NotificationPayloadBase): 

26 SCHEMA = { 

27 'uuid': ('instance', 'uuid'), 

28 'user_id': ('instance', 'user_id'), 

29 'tenant_id': ('instance', 'project_id'), 

30 'reservation_id': ('instance', 'reservation_id'), 

31 'display_name': ('instance', 'display_name'), 

32 'display_description': ('instance', 'display_description'), 

33 'host_name': ('instance', 'hostname'), 

34 'host': ('instance', 'host'), 

35 'node': ('instance', 'node'), 

36 'os_type': ('instance', 'os_type'), 

37 'architecture': ('instance', 'architecture'), 

38 'availability_zone': ('instance', 'availability_zone'), 

39 

40 'image_uuid': ('instance', 'image_ref'), 

41 

42 'key_name': ('instance', 'key_name'), 

43 

44 'kernel_id': ('instance', 'kernel_id'), 

45 'ramdisk_id': ('instance', 'ramdisk_id'), 

46 

47 'created_at': ('instance', 'created_at'), 

48 'launched_at': ('instance', 'launched_at'), 

49 'terminated_at': ('instance', 'terminated_at'), 

50 'deleted_at': ('instance', 'deleted_at'), 

51 'updated_at': ('instance', 'updated_at'), 

52 

53 'state': ('instance', 'vm_state'), 

54 'power_state': ('instance', 'power_state'), 

55 'task_state': ('instance', 'task_state'), 

56 'progress': ('instance', 'progress'), 

57 

58 'metadata': ('instance', 'metadata'), 

59 'locked': ('instance', 'locked'), 

60 'auto_disk_config': ('instance', 'auto_disk_config') 

61 } 

62 # Version 1.0: Initial version 

63 # Version 1.1: add locked and display_description field 

64 # Version 1.2: Add auto_disk_config field 

65 # Version 1.3: Add key_name field 

66 # Version 1.4: Add BDM related data 

67 # Version 1.5: Add updated_at field 

68 # Version 1.6: Add request_id field 

69 # Version 1.7: Added action_initiator_user and action_initiator_project to 

70 # InstancePayload 

71 # Version 1.8: Added locked_reason field 

72 # Version 1.9: Add shares related data 

73 VERSION = '1.9' 

74 fields = { 

75 'uuid': fields.UUIDField(), 

76 'user_id': fields.StringField(nullable=True), 

77 'tenant_id': fields.StringField(nullable=True), 

78 'reservation_id': fields.StringField(nullable=True), 

79 'display_name': fields.StringField(nullable=True), 

80 'display_description': fields.StringField(nullable=True), 

81 'host_name': fields.StringField(nullable=True), 

82 'host': fields.StringField(nullable=True), 

83 'node': fields.StringField(nullable=True), 

84 'os_type': fields.StringField(nullable=True), 

85 'architecture': fields.StringField(nullable=True), 

86 'availability_zone': fields.StringField(nullable=True), 

87 

88 'flavor': fields.ObjectField('FlavorPayload'), 

89 'image_uuid': fields.StringField(nullable=True), 

90 

91 'key_name': fields.StringField(nullable=True), 

92 

93 'kernel_id': fields.StringField(nullable=True), 

94 'ramdisk_id': fields.StringField(nullable=True), 

95 

96 'created_at': fields.DateTimeField(nullable=True), 

97 'launched_at': fields.DateTimeField(nullable=True), 

98 'terminated_at': fields.DateTimeField(nullable=True), 

99 'deleted_at': fields.DateTimeField(nullable=True), 

100 'updated_at': fields.DateTimeField(nullable=True), 

101 

102 'state': fields.InstanceStateField(nullable=True), 

103 'power_state': fields.InstancePowerStateField(nullable=True), 

104 'task_state': fields.InstanceTaskStateField(nullable=True), 

105 'progress': fields.IntegerField(nullable=True), 

106 

107 'ip_addresses': fields.ListOfObjectsField('IpPayload'), 

108 'block_devices': fields.ListOfObjectsField('BlockDevicePayload', 

109 nullable=True), 

110 

111 'metadata': fields.DictOfStringsField(), 

112 'locked': fields.BooleanField(), 

113 'auto_disk_config': fields.DiskConfigField(), 

114 

115 'request_id': fields.StringField(nullable=True), 

116 'action_initiator_user': fields.StringField(nullable=True), 

117 'action_initiator_project': fields.StringField(nullable=True), 

118 'locked_reason': fields.StringField(nullable=True), 

119 'shares': fields.ListOfObjectsField('SharePayload', nullable=True), 

120 } 

121 

122 def __init__(self, context, instance, bdms=None): 

123 super(InstancePayload, self).__init__() 

124 network_info = instance.get_network_info() 

125 self.ip_addresses = IpPayload.from_network_info(network_info) 

126 self.flavor = flavor_payload.FlavorPayload(flavor=instance.flavor) 

127 if bdms is not None: 

128 self.block_devices = BlockDevicePayload.from_bdms(bdms) 

129 else: 

130 self.block_devices = BlockDevicePayload.from_instance(instance) 

131 self.shares = SharePayload.from_instance(instance) 

132 # NOTE(Kevin_Zheng): Don't include request_id for periodic tasks, 

133 # RequestContext for periodic tasks does not include project_id 

134 # and user_id. Consider modify this once periodic tasks got a 

135 # consistent request_id. 

136 self.request_id = context.request_id if (context.project_id and 

137 context.user_id) else None 

138 self.action_initiator_user = context.user_id 

139 self.action_initiator_project = context.project_id 

140 self.locked_reason = instance.system_metadata.get("locked_reason") 

141 self.populate_schema(instance=instance) 

142 

143 

144@nova_base.NovaObjectRegistry.register_notification 

145class InstanceActionPayload(InstancePayload): 

146 # No SCHEMA as all the additional fields are calculated 

147 

148 # Version 1.1: locked and display_description added to InstancePayload 

149 # Version 1.2: Added auto_disk_config field to InstancePayload 

150 # Version 1.3: Added key_name field to InstancePayload 

151 # Version 1.4: Add BDM related data 

152 # Version 1.5: Added updated_at field to InstancePayload 

153 # Version 1.6: Added request_id field to InstancePayload 

154 # Version 1.7: Added action_initiator_user and action_initiator_project to 

155 # InstancePayload 

156 # Version 1.8: Added locked_reason field to InstancePayload 

157 # Version 1.9: Add shares related data 

158 VERSION = '1.9' 

159 fields = { 

160 'fault': fields.ObjectField('ExceptionPayload', nullable=True), 

161 'request_id': fields.StringField(nullable=True), 

162 } 

163 

164 def __init__(self, context, instance, fault, bdms=None): 

165 super(InstanceActionPayload, self).__init__(context=context, 

166 instance=instance, 

167 bdms=bdms) 

168 self.fault = fault 

169 

170 

171@nova_base.NovaObjectRegistry.register_notification 

172class InstanceActionVolumePayload(InstanceActionPayload): 

173 # Version 1.0: Initial version 

174 # Version 1.1: Added key_name field to InstancePayload 

175 # Version 1.2: Add BDM related data 

176 # Version 1.3: Added updated_at field to InstancePayload 

177 # Version 1.4: Added request_id field to InstancePayload 

178 # Version 1.5: Added action_initiator_user and action_initiator_project to 

179 # InstancePayload 

180 # Version 1.6: Added locked_reason field to InstancePayload 

181 # Version 1.7: Add shares to InstancePayload 

182 VERSION = '1.7' 

183 fields = { 

184 'volume_id': fields.UUIDField() 

185 } 

186 

187 def __init__(self, context, instance, fault, volume_id): 

188 super(InstanceActionVolumePayload, self).__init__( 

189 context=context, 

190 instance=instance, 

191 fault=fault) 

192 self.volume_id = volume_id 

193 

194 

195@nova_base.NovaObjectRegistry.register_notification 

196class InstanceActionSharePayload(InstanceActionPayload): 

197 # Version 1.0: Initial version 

198 VERSION = '1.0' 

199 fields = { 

200 'share_id': fields.UUIDField(), 

201 } 

202 

203 def __init__(self, context, instance, fault, share_id): 

204 super(InstanceActionSharePayload, self).__init__( 

205 context=context, 

206 instance=instance, 

207 fault=fault) 

208 self.share_id = share_id 

209 

210 

211@nova_base.NovaObjectRegistry.register_notification 

212class InstanceActionVolumeSwapPayload(InstanceActionPayload): 

213 # No SCHEMA as all the additional fields are calculated 

214 

215 # Version 1.1: locked and display_description added to InstancePayload 

216 # Version 1.2: Added auto_disk_config field to InstancePayload 

217 # Version 1.3: Added key_name field to InstancePayload 

218 # Version 1.4: Add BDM related data 

219 # Version 1.5: Added updated_at field to InstancePayload 

220 # Version 1.6: Added request_id field to InstancePayload 

221 # Version 1.7: Added action_initiator_user and action_initiator_project to 

222 # InstancePayload 

223 # Version 1.8: Added locked_reason field to InstancePayload 

224 # Version 1.9: Add shares to InstancePayload 

225 VERSION = '1.9' 

226 fields = { 

227 'old_volume_id': fields.UUIDField(), 

228 'new_volume_id': fields.UUIDField(), 

229 } 

230 

231 def __init__(self, context, instance, fault, old_volume_id, new_volume_id): 

232 super(InstanceActionVolumeSwapPayload, self).__init__( 

233 context=context, 

234 instance=instance, 

235 fault=fault) 

236 self.old_volume_id = old_volume_id 

237 self.new_volume_id = new_volume_id 

238 

239 

240@nova_base.NovaObjectRegistry.register_notification 

241class InstanceCreatePayload(InstanceActionPayload): 

242 # No SCHEMA as all the additional fields are calculated 

243 

244 # Version 1.2: Initial version. It starts at 1.2 to match with the version 

245 # of the InstanceActionPayload at the time when this specific 

246 # payload is created as a child of it so that the 

247 # instance.create notification using this new payload does not 

248 # have decreasing version. 

249 # 1.3: Add keypairs field 

250 # 1.4: Add key_name field to InstancePayload 

251 # 1.5: Add BDM related data to InstancePayload 

252 # 1.6: Add tags field to InstanceCreatePayload 

253 # 1.7: Added updated_at field to InstancePayload 

254 # 1.8: Added request_id field to InstancePayload 

255 # 1.9: Add trusted_image_certificates field to 

256 # InstanceCreatePayload 

257 # 1.10: Added action_initiator_user and action_initiator_project to 

258 # InstancePayload 

259 # 1.11: Added instance_name to InstanceCreatePayload 

260 # Version 1.12: Added locked_reason field to InstancePayload 

261 # Version 1.13: Add shares to InstancePayload 

262 VERSION = '1.13' 

263 fields = { 

264 'keypairs': fields.ListOfObjectsField('KeypairPayload'), 

265 'tags': fields.ListOfStringsField(), 

266 'trusted_image_certificates': fields.ListOfStringsField( 

267 nullable=True), 

268 'instance_name': fields.StringField(nullable=True), 

269 } 

270 

271 def __init__(self, context, instance, fault, bdms): 

272 super(InstanceCreatePayload, self).__init__( 

273 context=context, 

274 instance=instance, 

275 fault=fault, 

276 bdms=bdms) 

277 self.keypairs = [keypair_payload.KeypairPayload(keypair=keypair) 

278 for keypair in instance.keypairs] 

279 self.tags = [instance_tag.tag 

280 for instance_tag in instance.tags] 

281 self.trusted_image_certificates = None 

282 if instance.trusted_certs: 282 ↛ 283line 282 didn't jump to line 283 because the condition on line 282 was never true

283 self.trusted_image_certificates = instance.trusted_certs.ids 

284 self.instance_name = instance.name 

285 

286 

287@nova_base.NovaObjectRegistry.register_notification 

288class InstanceActionResizePrepPayload(InstanceActionPayload): 

289 # No SCHEMA as all the additional fields are calculated 

290 

291 # Version 1.0: Initial version 

292 # Version 1.1: Added request_id field to InstancePayload 

293 # Version 1.2: Added action_initiator_user and action_initiator_project to 

294 # InstancePayload 

295 # Version 1.3: Added locked_reason field to InstancePayload 

296 # Version 1.4: Add shares to InstancePayload 

297 VERSION = '1.4' 

298 fields = { 

299 'new_flavor': fields.ObjectField('FlavorPayload', nullable=True) 

300 } 

301 

302 def __init__(self, context, instance, fault, new_flavor): 

303 super(InstanceActionResizePrepPayload, self).__init__( 

304 context=context, 

305 instance=instance, 

306 fault=fault) 

307 self.new_flavor = new_flavor 

308 

309 

310@nova_base.NovaObjectRegistry.register_notification 

311class InstanceUpdatePayload(InstancePayload): 

312 # Version 1.0: Initial version 

313 # Version 1.1: locked and display_description added to InstancePayload 

314 # Version 1.2: Added tags field 

315 # Version 1.3: Added auto_disk_config field to InstancePayload 

316 # Version 1.4: Added key_name field to InstancePayload 

317 # Version 1.5: Add BDM related data 

318 # Version 1.6: Added updated_at field to InstancePayload 

319 # Version 1.7: Added request_id field to InstancePayload 

320 # Version 1.8: Added action_initiator_user and action_initiator_project to 

321 # InstancePayload 

322 # Version 1.9: Added locked_reason field to InstancePayload 

323 # Version 2.0: Remove bandwidth field 

324 # Version 2.1: Add shares to InstancePayload 

325 VERSION = '2.1' 

326 fields = { 

327 'state_update': fields.ObjectField('InstanceStateUpdatePayload'), 

328 'audit_period': fields.ObjectField('AuditPeriodPayload'), 

329 'old_display_name': fields.StringField(nullable=True), 

330 'tags': fields.ListOfStringsField(), 

331 } 

332 

333 def __init__( 

334 self, context, instance, state_update, audit_period, old_display_name, 

335 ): 

336 super().__init__(context=context, instance=instance) 

337 self.state_update = state_update 

338 self.audit_period = audit_period 

339 self.old_display_name = old_display_name 

340 self.tags = [instance_tag.tag 

341 for instance_tag in instance.tags.objects] 

342 

343 

344@nova_base.NovaObjectRegistry.register_notification 

345class InstanceActionRescuePayload(InstanceActionPayload): 

346 # Version 1.0: Initial version 

347 # Version 1.1: Added request_id field to InstancePayload 

348 # Version 1.2: Added action_initiator_user and action_initiator_project to 

349 # InstancePayload 

350 # Version 1.3: Added locked_reason field to InstancePayload 

351 # Version 1.4: Add shares to InstancePayload 

352 VERSION = '1.4' 

353 fields = { 

354 'rescue_image_ref': fields.UUIDField(nullable=True) 

355 } 

356 

357 def __init__(self, context, instance, fault, rescue_image_ref): 

358 super(InstanceActionRescuePayload, self).__init__( 

359 context=context, 

360 instance=instance, 

361 fault=fault) 

362 self.rescue_image_ref = rescue_image_ref 

363 

364 

365@nova_base.NovaObjectRegistry.register_notification 

366class InstanceActionRebuildPayload(InstanceActionPayload): 

367 # No SCHEMA as all the additional fields are calculated 

368 

369 # Version 1.7: Initial version. It starts at 1.7 to equal one more than 

370 # the version of the InstanceActionPayload at the time 

371 # when this specific payload is created so that the 

372 # instance.rebuild.* notifications using this new payload 

373 # signal the change of nova_object.name. 

374 # Version 1.8: Added action_initiator_user and action_initiator_project to 

375 # InstancePayload 

376 # Version 1.9: Added locked_reason field to InstancePayload 

377 # Version 1.10: Add shares to InstancePayload 

378 VERSION = '1.10' 

379 fields = { 

380 'trusted_image_certificates': fields.ListOfStringsField( 

381 nullable=True) 

382 } 

383 

384 def __init__(self, context, instance, fault, bdms=None): 

385 super(InstanceActionRebuildPayload, self).__init__( 

386 context=context, 

387 instance=instance, 

388 fault=fault, 

389 bdms=bdms) 

390 self.trusted_image_certificates = None 

391 if instance.trusted_certs: 391 ↛ 392line 391 didn't jump to line 392 because the condition on line 391 was never true

392 self.trusted_image_certificates = instance.trusted_certs.ids 

393 

394 

395@nova_base.NovaObjectRegistry.register_notification 

396class IpPayload(base.NotificationPayloadBase): 

397 # Version 1.0: Initial version 

398 VERSION = '1.0' 

399 fields = { 

400 'label': fields.StringField(), 

401 'mac': fields.MACAddressField(), 

402 'meta': fields.DictOfStringsField(), 

403 'port_uuid': fields.UUIDField(nullable=True), 

404 'version': fields.IntegerField(), 

405 'address': fields.IPV4AndV6AddressField(), 

406 'device_name': fields.StringField(nullable=True) 

407 } 

408 

409 def __init__(self, label, mac, meta, port_uuid, version, address, 

410 device_name): 

411 super(IpPayload, self).__init__() 

412 self.label = label 

413 self.mac = mac 

414 self.meta = meta 

415 self.port_uuid = port_uuid 

416 self.version = version 

417 self.address = address 

418 self.device_name = device_name 

419 

420 @classmethod 

421 def from_network_info(cls, network_info): 

422 """Returns a list of IpPayload object based on the passed 

423 network_info. 

424 """ 

425 ips = [] 

426 if network_info is not None: 

427 for vif in network_info: 

428 for ip in vif.fixed_ips(): 

429 ips.append(cls( 

430 label=vif["network"]["label"], 

431 mac=vif["address"], 

432 meta=vif["meta"], 

433 port_uuid=vif["id"], 

434 version=ip["version"], 

435 address=ip["address"], 

436 device_name=vif["devname"])) 

437 return ips 

438 

439 

440@nova_base.NovaObjectRegistry.register_notification 

441class AuditPeriodPayload(base.NotificationPayloadBase): 

442 # Version 1.0: Initial version 

443 VERSION = '1.0' 

444 fields = { 

445 'audit_period_beginning': fields.DateTimeField(), 

446 'audit_period_ending': fields.DateTimeField(), 

447 } 

448 

449 def __init__(self, audit_period_beginning, audit_period_ending): 

450 super(AuditPeriodPayload, self).__init__() 

451 self.audit_period_beginning = audit_period_beginning 

452 self.audit_period_ending = audit_period_ending 

453 

454 

455@nova_base.NovaObjectRegistry.register_notification 

456class BlockDevicePayload(base.NotificationPayloadBase): 

457 # Version 1.0: Initial version 

458 VERSION = '1.0' 

459 

460 SCHEMA = { 

461 'device_name': ('bdm', 'device_name'), 

462 'boot_index': ('bdm', 'boot_index'), 

463 'delete_on_termination': ('bdm', 'delete_on_termination'), 

464 'volume_id': ('bdm', 'volume_id'), 

465 'tag': ('bdm', 'tag') 

466 } 

467 

468 fields = { 

469 'device_name': fields.StringField(nullable=True), 

470 'boot_index': fields.IntegerField(nullable=True), 

471 'delete_on_termination': fields.BooleanField(default=False), 

472 'volume_id': fields.UUIDField(), 

473 'tag': fields.StringField(nullable=True) 

474 } 

475 

476 def __init__(self, bdm): 

477 super(BlockDevicePayload, self).__init__() 

478 self.populate_schema(bdm=bdm) 

479 

480 @classmethod 

481 def from_instance(cls, instance): 

482 """Returns a list of BlockDevicePayload objects based on the passed 

483 bdms. 

484 """ 

485 if not CONF.notifications.bdms_in_notifications: 

486 return None 

487 

488 instance_bdms = instance.get_bdms() 

489 if instance_bdms is not None: 489 ↛ 492line 489 didn't jump to line 492 because the condition on line 489 was always true

490 return cls.from_bdms(instance_bdms) 

491 else: 

492 return [] 

493 

494 @classmethod 

495 def from_bdms(cls, bdms): 

496 """Returns a list of BlockDevicePayload objects based on the passed 

497 BlockDeviceMappingList. 

498 """ 

499 payloads = [] 

500 for bdm in bdms: 

501 if bdm.volume_id is not None: 

502 payloads.append(cls(bdm)) 

503 return payloads 

504 

505 

506@nova_base.NovaObjectRegistry.register_notification 

507class SharePayload(base.NotificationPayloadBase): 

508 # Version 1.0: Initial version 

509 VERSION = '1.0' 

510 

511 SCHEMA = { 

512 'share_mapping_uuid': ('share', 'uuid'), 

513 'share_id': ('share', 'share_id'), 

514 'status': ('share', 'status'), 

515 'tag': ('share', 'tag'), 

516 # Do not include 'export_location' as it could contains sensitive data 

517 # 'export_location': ('share', 'export_location') 

518 } 

519 

520 fields = { 

521 'share_mapping_uuid': fields.UUIDField(), 

522 'share_id': fields.UUIDField(), 

523 'status': fields.StringField(nullable=False), 

524 'tag': fields.StringField(nullable=False), 

525 # 'export_location': fields.StringField(nullable=False), 

526 } 

527 

528 def __init__(self, share): 

529 super(SharePayload, self).__init__() 

530 self.populate_schema(share=share) 

531 

532 @classmethod 

533 def from_instance(cls, instance): 

534 """Returns a list of SharePayload objects based on the passed 

535 shares. 

536 """ 

537 if not CONF.notifications.include_share_mapping: 

538 return None 

539 

540 instance_shares = instance.get_shares() 

541 return [cls(share) for share in instance_shares] 

542 

543 @classmethod 

544 def from_shares(cls, shares): 

545 """Returns a list of SharePayload objects based on the passed 

546 ShareMappingList. 

547 """ 

548 return [cls(share) for share in shares] 

549 

550 

551@nova_base.NovaObjectRegistry.register_notification 

552class InstanceStateUpdatePayload(base.NotificationPayloadBase): 

553 # Version 1.0: Initial version 

554 VERSION = '1.0' 

555 fields = { 

556 'old_state': fields.StringField(nullable=True), 

557 'state': fields.StringField(nullable=True), 

558 'old_task_state': fields.StringField(nullable=True), 

559 'new_task_state': fields.StringField(nullable=True), 

560 } 

561 

562 def __init__(self, old_state, state, old_task_state, new_task_state): 

563 super(InstanceStateUpdatePayload, self).__init__() 

564 self.old_state = old_state 

565 self.state = state 

566 self.old_task_state = old_task_state 

567 self.new_task_state = new_task_state 

568 

569 

570@base.notification_sample('instance-delete-start.json') 

571@base.notification_sample('instance-delete-end.json') 

572@base.notification_sample('instance-pause-start.json') 

573@base.notification_sample('instance-pause-end.json') 

574@base.notification_sample('instance-unpause-start.json') 

575@base.notification_sample('instance-unpause-end.json') 

576@base.notification_sample('instance-resize-start.json') 

577@base.notification_sample('instance-resize-end.json') 

578@base.notification_sample('instance-resize-error.json') 

579@base.notification_sample('instance-suspend-start.json') 

580@base.notification_sample('instance-suspend-end.json') 

581@base.notification_sample('instance-power_on-start.json') 

582@base.notification_sample('instance-power_on_share-start.json') 

583@base.notification_sample('instance-power_on-end.json') 

584@base.notification_sample('instance-power_on_share-end.json') 

585@base.notification_sample('instance-power_off-start.json') 

586@base.notification_sample('instance-power_off-end.json') 

587@base.notification_sample('instance-reboot-start.json') 

588@base.notification_sample('instance-reboot-end.json') 

589@base.notification_sample('instance-reboot-error.json') 

590@base.notification_sample('instance-shutdown-start.json') 

591@base.notification_sample('instance-shutdown-end.json') 

592@base.notification_sample('instance-interface_attach-start.json') 

593@base.notification_sample('instance-interface_attach-end.json') 

594@base.notification_sample('instance-interface_attach-error.json') 

595@base.notification_sample('instance-shelve-start.json') 

596@base.notification_sample('instance-shelve-end.json') 

597@base.notification_sample('instance-resume-start.json') 

598@base.notification_sample('instance-resume-end.json') 

599@base.notification_sample('instance-restore-start.json') 

600@base.notification_sample('instance-restore-end.json') 

601@base.notification_sample('instance-evacuate.json') 

602@base.notification_sample('instance-resize_finish-start.json') 

603@base.notification_sample('instance-resize_finish-end.json') 

604@base.notification_sample('instance-live_migration_pre-start.json') 

605@base.notification_sample('instance-live_migration_pre-end.json') 

606@base.notification_sample('instance-live_migration_abort-start.json') 

607@base.notification_sample('instance-live_migration_abort-end.json') 

608@base.notification_sample('instance-live_migration_post-start.json') 

609@base.notification_sample('instance-live_migration_post-end.json') 

610@base.notification_sample('instance-live_migration_post_dest-start.json') 

611@base.notification_sample('instance-live_migration_post_dest-end.json') 

612@base.notification_sample('instance-live_migration_rollback-start.json') 

613@base.notification_sample('instance-live_migration_rollback-end.json') 

614@base.notification_sample('instance-live_migration_rollback_dest-start.json') 

615@base.notification_sample('instance-live_migration_rollback_dest-end.json') 

616@base.notification_sample('instance-interface_detach-start.json') 

617@base.notification_sample('instance-interface_detach-end.json') 

618@base.notification_sample('instance-resize_confirm-start.json') 

619@base.notification_sample('instance-resize_confirm-end.json') 

620@base.notification_sample('instance-resize_revert-start.json') 

621@base.notification_sample('instance-resize_revert-end.json') 

622@base.notification_sample('instance-live_migration_force_complete-start.json') 

623@base.notification_sample('instance-live_migration_force_complete-end.json') 

624@base.notification_sample('instance-shelve_offload-start.json') 

625@base.notification_sample('instance-shelve_offload-end.json') 

626@base.notification_sample('instance-soft_delete-start.json') 

627@base.notification_sample('instance-soft_delete-end.json') 

628@base.notification_sample('instance-trigger_crash_dump-start.json') 

629@base.notification_sample('instance-trigger_crash_dump-end.json') 

630@base.notification_sample('instance-unrescue-start.json') 

631@base.notification_sample('instance-unrescue-end.json') 

632@base.notification_sample('instance-unshelve-start.json') 

633@base.notification_sample('instance-unshelve-end.json') 

634@base.notification_sample('instance-lock.json') 

635@base.notification_sample('instance-unlock.json') 

636@nova_base.NovaObjectRegistry.register_notification 

637class InstanceActionNotification(base.NotificationBase): 

638 # Version 1.0: Initial version 

639 VERSION = '1.0' 

640 

641 fields = { 

642 'payload': fields.ObjectField('InstanceActionPayload') 

643 } 

644 

645 

646@base.notification_sample('instance-update.json') 

647@nova_base.NovaObjectRegistry.register_notification 

648class InstanceUpdateNotification(base.NotificationBase): 

649 # Version 1.0: Initial version 

650 VERSION = '1.0' 

651 

652 fields = { 

653 'payload': fields.ObjectField('InstanceUpdatePayload') 

654 } 

655 

656 

657@base.notification_sample('instance-volume_swap-start.json') 

658@base.notification_sample('instance-volume_swap-end.json') 

659@base.notification_sample('instance-volume_swap-error.json') 

660@nova_base.NovaObjectRegistry.register_notification 

661class InstanceActionVolumeSwapNotification(base.NotificationBase): 

662 # Version 1.0: Initial version 

663 VERSION = '1.0' 

664 

665 fields = { 

666 'payload': fields.ObjectField('InstanceActionVolumeSwapPayload') 

667 } 

668 

669 

670@base.notification_sample('instance-volume_attach-start.json') 

671@base.notification_sample('instance-volume_attach-end.json') 

672@base.notification_sample('instance-volume_attach-error.json') 

673@base.notification_sample('instance-volume_detach-start.json') 

674@base.notification_sample('instance-volume_detach-end.json') 

675@nova_base.NovaObjectRegistry.register_notification 

676class InstanceActionVolumeNotification(base.NotificationBase): 

677 # Version 1.0: Initial version 

678 VERSION = '1.0' 

679 

680 fields = { 

681 'payload': fields.ObjectField('InstanceActionVolumePayload') 

682 } 

683 

684 

685@base.notification_sample('instance-share_attach-start.json') 

686@base.notification_sample('instance-share_attach-error.json') 

687@base.notification_sample('instance-share_attach-end.json') 

688@base.notification_sample('instance-share_detach-start.json') 

689@base.notification_sample('instance-share_detach-error.json') 

690@base.notification_sample('instance-share_detach-end.json') 

691@nova_base.NovaObjectRegistry.register_notification 

692class InstanceActionShareNotification(base.NotificationBase): 

693 # Version 1.0: Initial version 

694 VERSION = '1.0' 

695 

696 fields = { 

697 'payload': fields.ObjectField('InstanceActionSharePayload') 

698 } 

699 

700 

701@base.notification_sample('instance-create-start.json') 

702@base.notification_sample('instance-create-end.json') 

703@base.notification_sample('instance-create-error.json') 

704@nova_base.NovaObjectRegistry.register_notification 

705class InstanceCreateNotification(base.NotificationBase): 

706 # Version 1.0: Initial version 

707 VERSION = '1.0' 

708 

709 fields = { 

710 'payload': fields.ObjectField('InstanceCreatePayload') 

711 } 

712 

713 

714@base.notification_sample('instance-resize_prep-start.json') 

715@base.notification_sample('instance-resize_prep-end.json') 

716@nova_base.NovaObjectRegistry.register_notification 

717class InstanceActionResizePrepNotification(base.NotificationBase): 

718 # Version 1.0: Initial version 

719 VERSION = '1.0' 

720 

721 fields = { 

722 'payload': fields.ObjectField('InstanceActionResizePrepPayload') 

723 } 

724 

725 

726@base.notification_sample('instance-snapshot-start.json') 

727@base.notification_sample('instance-snapshot-end.json') 

728@nova_base.NovaObjectRegistry.register_notification 

729class InstanceActionSnapshotNotification(base.NotificationBase): 

730 # Version 1.0: Initial version 

731 VERSION = '1.0' 

732 

733 fields = { 

734 'payload': fields.ObjectField('InstanceActionSnapshotPayload') 

735 } 

736 

737 

738@base.notification_sample('instance-rescue-start.json') 

739@base.notification_sample('instance-rescue-end.json') 

740@nova_base.NovaObjectRegistry.register_notification 

741class InstanceActionRescueNotification(base.NotificationBase): 

742 # Version 1.0: Initial version 

743 VERSION = '1.0' 

744 

745 fields = { 

746 'payload': fields.ObjectField('InstanceActionRescuePayload') 

747 } 

748 

749 

750@base.notification_sample('instance-rebuild_scheduled.json') 

751@base.notification_sample('instance-rebuild-start.json') 

752@base.notification_sample('instance-rebuild-end.json') 

753@base.notification_sample('instance-rebuild-error.json') 

754@nova_base.NovaObjectRegistry.register_notification 

755class InstanceActionRebuildNotification(base.NotificationBase): 

756 # Version 1.0: Initial version 

757 VERSION = '1.0' 

758 

759 fields = { 

760 'payload': fields.ObjectField('InstanceActionRebuildPayload') 

761 } 

762 

763 

764@nova_base.NovaObjectRegistry.register_notification 

765class InstanceActionSnapshotPayload(InstanceActionPayload): 

766 # Version 1.6: Initial version. It starts at version 1.6 as 

767 # instance.snapshot.start and .end notifications are switched 

768 # from using InstanceActionPayload 1.5 to this new payload and 

769 # also it added a new field so we wanted to keep the version 

770 # number increasing to signal the change. 

771 # Version 1.7: Added request_id field to InstancePayload 

772 # Version 1.8: Added action_initiator_user and action_initiator_project to 

773 # InstancePayload 

774 # Version 1.9: Added locked_reason field to InstancePayload 

775 # Version 1.10: Add shares to InstancePayload 

776 VERSION = '1.10' 

777 fields = { 

778 'snapshot_image_id': fields.UUIDField(), 

779 } 

780 

781 def __init__(self, context, instance, fault, snapshot_image_id): 

782 super(InstanceActionSnapshotPayload, self).__init__( 

783 context=context, 

784 instance=instance, 

785 fault=fault) 

786 self.snapshot_image_id = snapshot_image_id 

787 

788 

789@nova_base.NovaObjectRegistry.register_notification 

790class InstanceExistsPayload(InstancePayload): 

791 # Version 1.0: Initial version 

792 # Version 1.1: Added action_initiator_user and action_initiator_project to 

793 # InstancePayload 

794 # Version 1.2: Added locked_reason field to InstancePayload 

795 # Version 2.0: Remove bandwidth field 

796 # Version 2.1: Add shares to InstancePayload 

797 VERSION = '2.1' 

798 fields = { 

799 'audit_period': fields.ObjectField('AuditPeriodPayload'), 

800 } 

801 

802 def __init__(self, context, instance, audit_period): 

803 super().__init__(context=context, instance=instance) 

804 self.audit_period = audit_period 

805 

806 

807@base.notification_sample('instance-exists.json') 

808@nova_base.NovaObjectRegistry.register_notification 

809class InstanceExistsNotification(base.NotificationBase): 

810 # Version 1.0: Initial version 

811 VERSION = '1.0' 

812 

813 fields = { 

814 'payload': fields.ObjectField('InstanceExistsPayload') 

815 }