Add JSON schema and test for network_data.json
Added JSON schema defining `network_data.json` contents and beefed up the MetadataTest functional test cases to use a real instance instead of a database shell. This way the tests see real data in the metadata service like a real network_data.json. Besides internal Nova consumption, this schema might be helpful to other tools (such as ironic or Glean) to validate human-generated `network_data.json` prior to using it. Co-Authored-By: Balazs Gibizer <balazs.gibizer@est.tech> Change-Id: Ie5a5a1fc81c7c2d3f61b72d19de464cfc9dab5ec
This commit is contained in:
parent
67d9b5114e
commit
69ee625a66
30
doc/api_schemas/config_drive.json
Normal file
30
doc/api_schemas/config_drive.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"meta_data": {
|
||||
"type": "object"
|
||||
},
|
||||
"network_data": {
|
||||
"type": "object"
|
||||
},
|
||||
"user_data": {
|
||||
"type": [
|
||||
"object",
|
||||
"array",
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
580
doc/api_schemas/network_data.json
Normal file
580
doc/api_schemas/network_data.json
Normal file
@ -0,0 +1,580 @@
|
||||
{
|
||||
"$schema": "http://openstack.org/nova/network_data.json#",
|
||||
"id": "http://openstack.org/nova/network_data.json",
|
||||
"type": "object",
|
||||
"title": "OpenStack Nova network metadata schema",
|
||||
"description": "Schema of Nova instance network configuration information",
|
||||
"required": [
|
||||
"links",
|
||||
"networks",
|
||||
"services"
|
||||
],
|
||||
"properties": {
|
||||
"links": {
|
||||
"$id": "#/properties/links",
|
||||
"type": "array",
|
||||
"title": "L2 interfaces settings",
|
||||
"items": {
|
||||
"$id": "#/properties/links/items",
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/l2_link"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/l2_bond"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/l2_vlan"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"networks": {
|
||||
"$id": "#/properties/networks",
|
||||
"type": "array",
|
||||
"title": "L3 networks",
|
||||
"items": {
|
||||
"$id": "#/properties/networks/items",
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/l3_ipv4_network"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/l3_ipv6_network"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"$ref": "#/definitions/services"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"l2_address": {
|
||||
"$id": "#/definitions/l2_address",
|
||||
"type": "string",
|
||||
"pattern": "(?i)^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$",
|
||||
"title": "L2 interface address",
|
||||
"examples": [
|
||||
"fa:16:3e:9c:bf:3d"
|
||||
]
|
||||
},
|
||||
"l2_id": {
|
||||
"$id": "#/definitions/l2_id",
|
||||
"type": "string",
|
||||
"title": "L2 interface ID",
|
||||
"examples": [
|
||||
"eth0"
|
||||
]
|
||||
},
|
||||
"l2_mtu": {
|
||||
"$id": "#/definitions/l2_mtu",
|
||||
"title": "L2 interface MTU",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number",
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"examples": [
|
||||
1500
|
||||
]
|
||||
},
|
||||
"l2_vif_id": {
|
||||
"$id": "#/definitions/l2_vif_id",
|
||||
"type": "string",
|
||||
"title": "Virtual interface ID",
|
||||
"examples": [
|
||||
"cd9f6d46-4a3a-43ab-a466-994af9db96fc"
|
||||
]
|
||||
},
|
||||
"l2_link": {
|
||||
"$id": "#/definitions/l2_link",
|
||||
"type": "object",
|
||||
"title": "L2 interface configuration settings",
|
||||
"required": [
|
||||
"ethernet_mac_address",
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/l2_id"
|
||||
},
|
||||
"ethernet_mac_address": {
|
||||
"$ref": "#/definitions/l2_address"
|
||||
},
|
||||
"mtu": {
|
||||
"$ref": "#/definitions/l2_mtu"
|
||||
},
|
||||
"type": {
|
||||
"$id": "#/definitions/l2_link/properties/type",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"bridge",
|
||||
"dvs",
|
||||
"hw_veb",
|
||||
"hyperv",
|
||||
"ovs",
|
||||
"tap",
|
||||
"vhostuser",
|
||||
"vif",
|
||||
"phy"
|
||||
],
|
||||
"title": "Interface type",
|
||||
"examples": [
|
||||
"bridge"
|
||||
]
|
||||
},
|
||||
"vif_id": {
|
||||
"$ref": "#/definitions/l2_vif_id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"l2_bond": {
|
||||
"$id": "#/definitions/l2_bond",
|
||||
"type": "object",
|
||||
"title": "L2 bonding interface configuration settings",
|
||||
"required": [
|
||||
"ethernet_mac_address",
|
||||
"id",
|
||||
"type",
|
||||
"bond_mode",
|
||||
"bond_links"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/l2_id"
|
||||
},
|
||||
"ethernet_mac_address": {
|
||||
"$ref": "#/definitions/l2_address"
|
||||
},
|
||||
"mtu": {
|
||||
"$ref": "#/definitions/l2_mtu"
|
||||
},
|
||||
"type": {
|
||||
"$id": "#/definitions/l2_bond/properties/type",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"bond"
|
||||
],
|
||||
"title": "Interface type",
|
||||
"examples": [
|
||||
"bond"
|
||||
]
|
||||
},
|
||||
"vif_id": {
|
||||
"$ref": "#/definitions/l2_vif_id"
|
||||
},
|
||||
"bond_mode": {
|
||||
"$id": "#/definitions/bond/properties/bond_mode",
|
||||
"type": "string",
|
||||
"title": "Port bonding type",
|
||||
"enum": [
|
||||
"802.1ad",
|
||||
"balance-rr",
|
||||
"active-backup",
|
||||
"balance-xor",
|
||||
"broadcast",
|
||||
"balance-tlb",
|
||||
"balance-alb"
|
||||
],
|
||||
"examples": [
|
||||
"802.1ad"
|
||||
]
|
||||
},
|
||||
"bond_links": {
|
||||
"$id": "#/definitions/bond/properties/bond_links",
|
||||
"type": "array",
|
||||
"title": "Port bonding links",
|
||||
"items": {
|
||||
"$id": "#/definitions/bond/properties/bond_links/items",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"l2_vlan": {
|
||||
"$id": "#/definitions/l2_vlan",
|
||||
"type": "object",
|
||||
"title": "L2 VLAN interface configuration settings",
|
||||
"required": [
|
||||
"vlan_mac_address",
|
||||
"id",
|
||||
"type",
|
||||
"vlan_link",
|
||||
"vlan_id"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/l2_id"
|
||||
},
|
||||
"vlan_mac_address": {
|
||||
"$ref": "#/definitions/l2_address"
|
||||
},
|
||||
"mtu": {
|
||||
"$ref": "#/definitions/l2_mtu"
|
||||
},
|
||||
"type": {
|
||||
"$id": "#/definitions/l2_vlan/properties/type",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"vlan"
|
||||
],
|
||||
"title": "VLAN interface type",
|
||||
"examples": [
|
||||
"vlan"
|
||||
]
|
||||
},
|
||||
"vif_id": {
|
||||
"$ref": "#/definitions/l2_vif_id"
|
||||
},
|
||||
"vlan_id": {
|
||||
"$id": "#/definitions/l2_vlan/properties/vlan_id",
|
||||
"type": "integer",
|
||||
"title": "VLAN ID"
|
||||
},
|
||||
"vlan_link": {
|
||||
"$id": "#/definitions/l2_vlan/properties/vlan_link",
|
||||
"type": "string",
|
||||
"title": "VLAN link name"
|
||||
}
|
||||
}
|
||||
},
|
||||
"l3_id": {
|
||||
"$id": "#/definitions/l3_id",
|
||||
"type": "string",
|
||||
"title": "Network name",
|
||||
"examples": [
|
||||
"network0"
|
||||
]
|
||||
},
|
||||
"l3_link": {
|
||||
"$id": "#/definitions/l3_link",
|
||||
"type": "string",
|
||||
"title": "L2 network link to use for L3 interface",
|
||||
"examples": [
|
||||
"99e88329-f20d-4741-9593-25bf07847b16"
|
||||
]
|
||||
},
|
||||
"l3_network_id": {
|
||||
"$id": "#/definitions/l3_network_id",
|
||||
"type": "string",
|
||||
"title": "Network ID",
|
||||
"examples": [
|
||||
"99e88329-f20d-4741-9593-25bf07847b16"
|
||||
]
|
||||
},
|
||||
"l3_ipv4_type": {
|
||||
"$id": "#/definitions/l3_ipv4_type",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ipv4",
|
||||
"ipv4_dhcp"
|
||||
],
|
||||
"title": "L3 IPv4 network type",
|
||||
"examples": [
|
||||
"ipv4_dhcp"
|
||||
]
|
||||
},
|
||||
"l3_ipv6_type": {
|
||||
"$id": "#/definitions/l3_ipv6_type",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ipv6",
|
||||
"ipv6_dhcp",
|
||||
"ipv6_slaac"
|
||||
],
|
||||
"title": "L3 IPv6 network type",
|
||||
"examples": [
|
||||
"ipv6_dhcp"
|
||||
]
|
||||
},
|
||||
"l3_ipv4_host": {
|
||||
"$id": "#/definitions/l3_ipv4_host",
|
||||
"type": "string",
|
||||
"pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$",
|
||||
"title": "L3 IPv4 host address",
|
||||
"examples": [
|
||||
"192.168.81.99"
|
||||
]
|
||||
},
|
||||
"l3_ipv6_host": {
|
||||
"$id": "#/definitions/l3_ipv6_host",
|
||||
"type": "string",
|
||||
"pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(/[0-9]{1,2})?$",
|
||||
"title": "L3 IPv6 host address",
|
||||
"examples": [
|
||||
"2001:db8:3:4::192.168.81.99"
|
||||
]
|
||||
},
|
||||
"l3_ipv4_netmask": {
|
||||
"$id": "#/definitions/l3_ipv4_netmask",
|
||||
"type": "string",
|
||||
"pattern": "^(254|252|248|240|224|192|128|0)\\.0\\.0\\.0|255\\.(254|252|248|240|224|192|128|0)\\.0\\.0|255\\.255\\.(254|252|248|240|224|192|128|0)\\.0|255\\.255\\.255\\.(254|252|248|240|224|192|128|0)$",
|
||||
"title": "L3 IPv4 network mask",
|
||||
"examples": [
|
||||
"255.255.252.0"
|
||||
]
|
||||
},
|
||||
"l3_ipv6_netmask": {
|
||||
"$id": "#/definitions/l3_ipv6_netmask",
|
||||
"type": "string",
|
||||
"pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7})|(::))$",
|
||||
"title": "L3 IPv6 network mask",
|
||||
"examples": [
|
||||
"ffff:ffff:ffff:ffff::"
|
||||
]
|
||||
},
|
||||
"l3_ipv4_nw": {
|
||||
"$id": "#/definitions/l3_ipv4_nw",
|
||||
"type": "string",
|
||||
"pattern": "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$",
|
||||
"title": "L3 IPv4 network address",
|
||||
"examples": [
|
||||
"0.0.0.0"
|
||||
]
|
||||
},
|
||||
"l3_ipv6_nw": {
|
||||
"$id": "#/definitions/l3_ipv6_nw",
|
||||
"type": "string",
|
||||
"pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7})|(::))$",
|
||||
"title": "L3 IPv6 network address",
|
||||
"examples": [
|
||||
"8000::"
|
||||
]
|
||||
},
|
||||
"l3_ipv4_gateway": {
|
||||
"$id": "#/definitions/l3_ipv4_gateway",
|
||||
"type": "string",
|
||||
"pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$",
|
||||
"title": "L3 IPv4 gateway address",
|
||||
"examples": [
|
||||
"192.168.200.1"
|
||||
]
|
||||
},
|
||||
"l3_ipv6_gateway": {
|
||||
"$id": "#/definitions/l3_ipv6_gateway",
|
||||
"type": "string",
|
||||
"pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$",
|
||||
"title": "L3 IPv6 gateway address",
|
||||
"examples": [
|
||||
"2001:db8:3:4::192.168.81.99"
|
||||
]
|
||||
},
|
||||
"l3_ipv4_network_route": {
|
||||
"$id": "#/definitions/l3_ipv4_network_route",
|
||||
"type": "object",
|
||||
"title": "L3 IPv4 routing configuration item",
|
||||
"required": [
|
||||
"gateway",
|
||||
"netmask",
|
||||
"network"
|
||||
],
|
||||
"properties": {
|
||||
"network": {
|
||||
"$ref": "#/definitions/l3_ipv4_nw"
|
||||
},
|
||||
"netmask": {
|
||||
"$ref": "#/definitions/l3_ipv4_netmask"
|
||||
},
|
||||
"gateway": {
|
||||
"$ref": "#/definitions/l3_ipv4_gateway"
|
||||
},
|
||||
"services": {
|
||||
"$ref": "#/definitions/ipv4_services"
|
||||
}
|
||||
}
|
||||
},
|
||||
"l3_ipv6_network_route": {
|
||||
"$id": "#/definitions/l3_ipv6_network_route",
|
||||
"type": "object",
|
||||
"title": "L3 IPv6 routing configuration item",
|
||||
"required": [
|
||||
"gateway",
|
||||
"netmask",
|
||||
"network"
|
||||
],
|
||||
"properties": {
|
||||
"network": {
|
||||
"$ref": "#/definitions/l3_ipv6_nw"
|
||||
},
|
||||
"netmask": {
|
||||
"$ref": "#/definitions/l3_ipv6_netmask"
|
||||
},
|
||||
"gateway": {
|
||||
"$ref": "#/definitions/l3_ipv6_gateway"
|
||||
},
|
||||
"services": {
|
||||
"$ref": "#/definitions/ipv6_services"
|
||||
}
|
||||
}
|
||||
},
|
||||
"l3_ipv4_network": {
|
||||
"$id": "#/definitions/l3_ipv4_network",
|
||||
"type": "object",
|
||||
"title": "L3 IPv4 network configuration",
|
||||
"required": [
|
||||
"id",
|
||||
"link",
|
||||
"network_id",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/l3_id"
|
||||
},
|
||||
"link": {
|
||||
"$ref": "#/definitions/l3_link"
|
||||
},
|
||||
"network_id": {
|
||||
"$ref": "#/definitions/l3_network_id"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/definitions/l3_ipv4_type"
|
||||
},
|
||||
"ip_address": {
|
||||
"$ref": "#/definitions/l3_ipv4_host"
|
||||
},
|
||||
"netmask": {
|
||||
"$ref": "#/definitions/l3_ipv4_netmask"
|
||||
},
|
||||
"routes": {
|
||||
"$id": "#/definitions/l3_ipv4_network/routes",
|
||||
"type": "array",
|
||||
"title": "L3 IPv4 network routes",
|
||||
"items": {
|
||||
"$ref": "#/definitions/l3_ipv4_network_route"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"l3_ipv6_network": {
|
||||
"$id": "#/definitions/l3_ipv6_network",
|
||||
"type": "object",
|
||||
"title": "L3 IPv6 network configuration",
|
||||
"required": [
|
||||
"id",
|
||||
"link",
|
||||
"network_id",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/l3_id"
|
||||
},
|
||||
"link": {
|
||||
"$ref": "#/definitions/l3_link"
|
||||
},
|
||||
"network_id": {
|
||||
"$ref": "#/definitions/l3_network_id"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/definitions/l3_ipv6_type"
|
||||
},
|
||||
"ip_address": {
|
||||
"$ref": "#/definitions/l3_ipv6_host"
|
||||
},
|
||||
"netmask": {
|
||||
"$ref": "#/definitions/l3_ipv6_netmask"
|
||||
},
|
||||
"routes": {
|
||||
"$id": "#/definitions/properties/l3_ipv6_network/routes",
|
||||
"type": "array",
|
||||
"title": "L3 IPv6 network routes",
|
||||
"items": {
|
||||
"$ref": "#/definitions/l3_ipv6_network_route"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ipv4_service": {
|
||||
"$id": "#/definitions/ipv4_service",
|
||||
"type": "object",
|
||||
"title": "Service on a IPv4 network",
|
||||
"required": [
|
||||
"address",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "#/definitions/l3_ipv4_host"
|
||||
},
|
||||
"type": {
|
||||
"$id": "#/definitions/ipv4_service/properties/type",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"dns"
|
||||
],
|
||||
"title": "Service type",
|
||||
"examples": [
|
||||
"dns"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ipv6_service": {
|
||||
"$id": "#/definitions/ipv6_service",
|
||||
"type": "object",
|
||||
"title": "Service on a IPv6 network",
|
||||
"required": [
|
||||
"address",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "#/definitions/l3_ipv6_host"
|
||||
},
|
||||
"type": {
|
||||
"$id": "#/definitions/ipv4_service/properties/type",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"dns"
|
||||
],
|
||||
"title": "Service type",
|
||||
"examples": [
|
||||
"dns"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ipv4_services": {
|
||||
"$id": "#/definitions/ipv4_services",
|
||||
"type": "array",
|
||||
"title": "Network services on IPv4 network",
|
||||
"items": {
|
||||
"$id": "#/definitions/ipv4_services/items",
|
||||
"$ref": "#/definitions/ipv4_service"
|
||||
}
|
||||
},
|
||||
"ipv6_services": {
|
||||
"$id": "#/definitions/ipv6_services",
|
||||
"type": "array",
|
||||
"title": "Network services on IPv6 network",
|
||||
"items": {
|
||||
"$id": "#/definitions/ipv6_services/items",
|
||||
"$ref": "#/definitions/ipv6_service"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"$id": "#/definitions/services",
|
||||
"type": "array",
|
||||
"title": "Network services",
|
||||
"items": {
|
||||
"$id": "#/definitions/services/items",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ipv4_service"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ipv6_service"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -337,6 +337,8 @@ example:
|
||||
}
|
||||
|
||||
|
||||
::download:`Download</../../doc/api_schemas/network_data.json>` network_data.json JSON schema.
|
||||
|
||||
.. _metadata-ec2-format:
|
||||
|
||||
EC2-compatible metadata
|
||||
|
@ -15,15 +15,18 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import fixtures
|
||||
import jsonschema
|
||||
import os
|
||||
import requests
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from nova import context
|
||||
from nova import objects
|
||||
from nova import test
|
||||
from nova.tests import fixtures as nova_fixtures
|
||||
from nova.tests.functional import fixtures as func_fixtures
|
||||
from nova.tests.functional import integrated_helpers
|
||||
from nova.tests.unit.image import fake as fake_image
|
||||
|
||||
|
||||
class fake_result(object):
|
||||
@ -45,45 +48,38 @@ def fake_request(obj, url, method, **kwargs):
|
||||
return real_request(method, url, **kwargs)
|
||||
|
||||
|
||||
class MetadataTest(test.TestCase):
|
||||
class MetadataTest(test.TestCase, integrated_helpers.InstanceHelperMixin):
|
||||
def setUp(self):
|
||||
super(MetadataTest, self).setUp()
|
||||
|
||||
fake_image.stub_out_image_service(self)
|
||||
self.addCleanup(fake_image.FakeImageService_reset)
|
||||
self.useFixture(nova_fixtures.NeutronFixture(self))
|
||||
self.useFixture(func_fixtures.PlacementFixture())
|
||||
self.start_service('conductor')
|
||||
self.start_service('scheduler')
|
||||
self.api = self.useFixture(
|
||||
nova_fixtures.OSAPIFixture(api_version='v2.1')).api
|
||||
self.start_service('compute')
|
||||
|
||||
# create a server for the tests
|
||||
server = self._build_server(name='test')
|
||||
server = self.api.post_server({'server': server})
|
||||
self.server = self._wait_for_state_change(server, 'ACTIVE')
|
||||
|
||||
self.api_fixture = self.useFixture(nova_fixtures.OSMetadataServer())
|
||||
self.md_url = self.api_fixture.md_url
|
||||
|
||||
ctxt = context.RequestContext('fake', 'fake')
|
||||
flavor = objects.Flavor(
|
||||
id=1, name='flavor1', memory_mb=256, vcpus=1, root_gb=1,
|
||||
ephemeral_gb=1, flavorid='1', swap=0, rxtx_factor=1.0,
|
||||
vcpu_weight=1, disabled=False, is_public=True, extra_specs={},
|
||||
projects=[])
|
||||
instance = objects.Instance(ctxt, flavor=flavor, vcpus=1,
|
||||
memory_mb=256, root_gb=0, ephemeral_gb=0,
|
||||
project_id='fake', hostname='test')
|
||||
instance.create()
|
||||
|
||||
# The NeutronFixture is needed to provide the fixed IP for the metadata
|
||||
# service
|
||||
self.useFixture(nova_fixtures.NeutronFixture(self))
|
||||
|
||||
# make sure that the metadata service returns information about the
|
||||
# server we created above
|
||||
def fake_get_fixed_ip_by_address(self, ctxt, address):
|
||||
return {'instance_uuid': instance.uuid}
|
||||
return {'instance_uuid': server['id']}
|
||||
|
||||
self.useFixture(
|
||||
fixtures.MonkeyPatch(
|
||||
'nova.network.neutronv2.api.API.get_fixed_ip_by_address',
|
||||
fake_get_fixed_ip_by_address))
|
||||
|
||||
def fake_get_ec2_ip_info(nw_info):
|
||||
return {'fixed_ips': ['127.0.0.2'],
|
||||
'fixed_ip6s': [],
|
||||
'floating_ips': []}
|
||||
|
||||
self.useFixture(
|
||||
fixtures.MonkeyPatch(
|
||||
'nova.virt.netutils.get_ec2_ip_info',
|
||||
fake_get_ec2_ip_info))
|
||||
|
||||
def test_lookup_metadata_root_url(self):
|
||||
res = requests.request('GET', self.md_url, timeout=5)
|
||||
self.assertEqual(200, res.status_code)
|
||||
@ -174,7 +170,25 @@ class MetadataTest(test.TestCase):
|
||||
self.assertIn('instance-id', j['testing'])
|
||||
self.assertTrue(uuidutils.is_uuid_like(j['testing']['instance-id']))
|
||||
self.assertIn('hostname', j['testing'])
|
||||
self.assertEqual('fake', j['testing']['project-id'])
|
||||
self.assertEqual(self.server['tenant_id'], j['testing']['project-id'])
|
||||
self.assertIn('metadata', j['testing'])
|
||||
self.assertIn('image-id', j['testing'])
|
||||
self.assertIn('user-data', j['testing'])
|
||||
|
||||
def test_network_data_matches_schema(self):
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'keystoneauth1.session.Session.request', fake_request))
|
||||
|
||||
url = '%sopenstack/latest/network_data.json' % self.md_url
|
||||
|
||||
res = requests.request('GET', url, timeout=5)
|
||||
self.assertEqual(200, res.status_code)
|
||||
|
||||
# load the jsonschema for network_data
|
||||
schema_file = os.path.normpath(os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"../../../doc/api_schemas/network_data.json"))
|
||||
with open(schema_file, 'rb') as f:
|
||||
schema = jsonutils.load(f)
|
||||
|
||||
jsonschema.validate(res.json(), schema)
|
||||
|
Loading…
Reference in New Issue
Block a user