Skip to content

Commit

Permalink
Merge pull request juju#17982 from wallyworld/network-device-dll
Browse files Browse the repository at this point in the history
juju#17982

Add the DDL to model various network artefacts, including
- link layer devices
- ip addresses and associated artefacts
- fqdn addresses
- hostname addresses
 - relationships between the above

A cloud container has 1:1 net node.
A cloud container has 0..N ports.

A net node has 0..N link layer devices.
A net node has 0..N FQDN addresses.
A net node has 0..N hostname addresses.

A link layer device has 0..1 IP addresses.

An IP address has 0..1 subnets.
An IP address has 0..1 gateway address values.
An IP address has 0..N DNS server addresses.
An IP address has 0..N DNS search domains.

v_address is used to combine fqdn and ip addresses since that's how juju currently models things internally.

Gateway address value could be a FK back to IP address - can change if we want to do that. Wasn't sure if we needed the extra address attributes or if we just wanted to record the value.

[
![network](https://github.com/user-attachments/assets/c5dd32ea-4293-42c9-b6e8-75a914ac462f)
](url)
## QA steps

unit tests

## Links

**Jira card:** [JUJU-6358](https://warthogs.atlassian.net/issues/JUJU-6358)



[JUJU-6358]: https://warthogs.atlassian.net/browse/JUJU-6358?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
jujubot authored Sep 2, 2024
2 parents 4658cde + 41f9de2 commit 31ac3af
Show file tree
Hide file tree
Showing 3 changed files with 372 additions and 0 deletions.
345 changes: 345 additions & 0 deletions domain/schema/model/sql/0020-network.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,354 @@ CREATE UNIQUE INDEX idx_cloud_service_application
ON cloud_service (application_uuid);

CREATE TABLE cloud_container (
-- one cloud container per net node.
net_node_uuid TEXT NOT NULL PRIMARY KEY,
-- provider_id comes from the provider, no FK.
provider_id TEXT NOT NULL,
CONSTRAINT fk_cloud_container_net_node
FOREIGN KEY (net_node_uuid)
REFERENCES net_node (uuid)
);

CREATE UNIQUE INDEX idx_cloud_container_provider
ON cloud_container (provider_id);

CREATE TABLE cloud_container_port (
cloud_container_uuid TEXT NOT NULL,
port TEXT NOT NULL,
CONSTRAINT fk_cloud_container_port_net_node
FOREIGN KEY (cloud_container_uuid)
REFERENCES cloud_container (net_node_uuid),
PRIMARY KEY (cloud_container_uuid, port)
);

CREATE TABLE link_layer_device_type (
id INT PRIMARY KEY,
name TEXT NOT NULL
);

CREATE UNIQUE INDEX idx_link_layer_device_type_name
ON link_layer_device_type (name);

INSERT INTO link_layer_device_type VALUES
(0, 'unknown'),
(1, 'loopback'),
(2, 'ethernet'),
(3, '802.1q'),
(4, 'bond'),
(5, 'bridge'),
(6, 'vxlan');

CREATE TABLE virtual_port_type (
id INT PRIMARY KEY,
name TEXT NOT NULL
);

CREATE UNIQUE INDEX idx_virtual_port_type_name
ON virtual_port_type (name);

INSERT INTO virtual_port_type VALUES
(0, 'nonvirtualport'),
(1, 'openvswitch');

CREATE TABLE link_layer_device (
uuid TEXT NOT NULL PRIMARY KEY,
net_node_uuid TEXT NOT NULL,
name TEXT NOT NULL,
mtu INT,
mac_address TEXT NOT NULL,
-- provider_id comes from the provider, no FK.
provider_id TEXT,
-- one of loopback, ethernet, bridge etc.
device_type_id INT NOT NULL,
-- one of nonvirtualport, openvswitch
virtual_port_type_id INT NOT NULL,
-- true if the device should be activated on boot.
is_auto_start BOOLEAN NOT NULL DEFAULT false,
-- true when the device is up (enabled).
is_enabled BOOLEAN NOT NULL DEFAULT true,
-- the link layer device which is the parent to this device.
parent_device_uuid TEXT,
CONSTRAINT fk_link_layer_device_parent_device
FOREIGN KEY (parent_device_uuid)
REFERENCES link_layer_device (uuid),
CONSTRAINT fk_link_layer_device_net_node
FOREIGN KEY (net_node_uuid)
REFERENCES net_node (uuid),
CONSTRAINT fk_link_layer_device_device_type
FOREIGN KEY (device_type_id)
REFERENCES link_layer_device_type (id),
CONSTRAINT fk_link_layer_device_virtual_port_type
FOREIGN KEY (virtual_port_type_id)
REFERENCES virtual_port_type (id)
);

-- ip_address_type represents the possible ways of specifying
-- an address, either a hostname resolvable by dns lookup,
-- or IPv4 or IPv6 address.
CREATE TABLE ip_address_type (
id INT PRIMARY KEY,
name TEXT NOT NULL
);

CREATE UNIQUE INDEX idx_ip_address_type_name
ON ip_address_type (name);

INSERT INTO ip_address_type VALUES
(0, 'ipv4'),
(1, 'ipv6');

-- ip_address_origin represents the authoritative source of
-- an ip address.
CREATE TABLE ip_address_origin (
id INT PRIMARY KEY,
name TEXT NOT NULL
);

CREATE UNIQUE INDEX idx_ip_address_origin_name
ON ip_address_origin (name);

INSERT INTO ip_address_origin VALUES
(0, 'host'),
(1, 'provider');

-- ip_address_scope denotes the context an ip address may apply to.
-- If an address can be reached from the wider internet,
-- it is considered public. A private ip address is either
-- specific to the cloud or cloud subnet a node belongs to,
-- or to the node itself for containers.
CREATE TABLE ip_address_scope (
id INT PRIMARY KEY,
name TEXT NOT NULL
);

CREATE UNIQUE INDEX idx_ip_address_scope_name
ON ip_address_scope (name);

INSERT INTO ip_address_scope VALUES
(0, 'unknown'),
(1, 'public'),
(2, 'local-cloud'),
(3, 'local-machine'),
(4, 'link-local');

-- ip_address_config_type defines valid network
-- link configuration types.
CREATE TABLE ip_address_config_type (
id INT PRIMARY KEY,
name TEXT NOT NULL
);

CREATE UNIQUE INDEX idx_ip_address_config_type_name
ON ip_address_config_type (name);

INSERT INTO ip_address_config_type VALUES
(0, 'unknown'),
(1, 'dhcp'),
(2, 'dhcpv6'),
(3, 'slaac'),
(4, 'static'),
(5, 'manual'),
(6, 'loopback');

CREATE TABLE ip_address (
uuid TEXT NOT NULL PRIMARY KEY,
-- The value of the configured IP address.
-- e.g. 192.168.1.2 or 2001:db8:0000:0000:0000:0000:0000:00001.
address_value TEXT NOT NULL,
-- one of ipv4, ipv6 etc.
type_id INT NOT NULL,
-- one of dhcp, static, manual, loopback etc.
config_type_id INT NOT NULL,
-- one of host, provider
origin_id INT NOT NULL,
-- one of public, local-cloud, local-machine, link-local etc.
scope_id INT NOT NULL,
-- the link layer device this address belongs to.
device_uuid TEXT NOT NULL,

CONSTRAINT fk_ip_address_link_layer_device
FOREIGN KEY (device_uuid)
REFERENCES link_layer_device (uuid),
CONSTRAINT fk_ip_address_origin
FOREIGN KEY (origin_id)
REFERENCES ip_address_origin (id),
CONSTRAINT fk_ip_address_type
FOREIGN KEY (type_id)
REFERENCES ip_address_type (id),
CONSTRAINT fk_ip_address_config_type
FOREIGN KEY (config_type_id)
REFERENCES ip_address_config_type (id),
CONSTRAINT fk_ip_address_scope
FOREIGN KEY (scope_id)
REFERENCES ip_address_scope (id)
);

CREATE TABLE net_node_ip_address (
address_uuid TEXT NOT NULL PRIMARY KEY,

-- indicates that this address is not the primary.
-- address associated with the NIC.
is_secondary BOOLEAN DEFAULT false,

-- indicates whether this address is a virtual/floating/shadow.
-- address assigned to a NIC by a provider rather than being
-- associated directly with a device on-machine.
is_shadow BOOLEAN DEFAULT false,

CONSTRAINT fk_net_node_ip_address_ip_address
FOREIGN KEY (address_uuid)
REFERENCES ip_address (uuid)
);

CREATE TABLE ip_address_dns_server_address (
address_uuid TEXT NOT NULL,
dns_server_address_uuid TEXT NOT NULL,
CONSTRAINT fk_ip_address_dns_server_address_dns_server_address
FOREIGN KEY (dns_server_address_uuid)
REFERENCES ip_address (uuid),
CONSTRAINT fk_ip_address_dns_server_address_ip_address
FOREIGN KEY (address_uuid)
REFERENCES ip_address (uuid),
PRIMARY KEY (dns_server_address_uuid, address_uuid)
);

CREATE TABLE ip_address_dns_search_domain (
address_uuid TEXT NOT NULL,
search_domain TEXT NOT NULL,
CONSTRAINT fk_ip_address_dns_search_domain_ip_address
FOREIGN KEY (address_uuid)
REFERENCES ip_address (uuid),
PRIMARY KEY (address_uuid, search_domain)
);

-- network_address_scope denotes the context a network address may apply to.
-- If an address can be reached from the wider internet,
-- it is considered public. A private address is either
-- specific to the cloud or cloud subnet a node belongs to,
-- or to the node itself for containers.
CREATE TABLE network_address_scope (
id INT PRIMARY KEY,
name TEXT NOT NULL
);

CREATE UNIQUE INDEX idx_network_address_scope_name
ON network_address_scope (name);

INSERT INTO network_address_scope VALUES
-- eg "foo"
(0, 'local-host'),
-- eg "foo.local", "foo.namespace.cluster.local"
(1, 'local-cloud'),
-- "eg "foo.example.com"
(2, 'public');

CREATE TABLE fqdn_address (
uuid TEXT NOT NULL PRIMARY KEY,
address TEXT NOT NULL,
-- one of local-cloud, public.
scope_id INT NOT NULL,

CONSTRAINT chk_fqdn_address_scope
CHECK (scope_id != 0), -- scope can't be local-host
CONSTRAINT fk_fqdn_address_scope
FOREIGN KEY (scope_id)
REFERENCES network_address_scope (id)
);

CREATE UNIQUE INDEX idx_fqdn_address_address
ON fqdn_address (address);

CREATE TABLE net_node_fqdn_address (
net_node_uuid TEXT NOT NULL,
address_uuid TEXT NOT NULL,
CONSTRAINT fk_net_node_fqdn_address_net_node
FOREIGN KEY (net_node_uuid)
REFERENCES net_node (uuid),
CONSTRAINT fk_net_node_fqdn_address_address
FOREIGN KEY (address_uuid)
REFERENCES fqdn_address (uuid),
PRIMARY KEY (net_node_uuid, address_uuid)
);

CREATE TABLE hostname_address (
uuid TEXT NOT NULL PRIMARY KEY,
hostname TEXT NOT NULL,
-- one of local-host, local-cloud, public.
scope_id INT NOT NULL,

CONSTRAINT fk_hostname_address_scope
FOREIGN KEY (scope_id)
REFERENCES network_address_scope (id)
);

CREATE UNIQUE INDEX idx_hostname_address_hostname
ON hostname_address (hostname);

CREATE TABLE net_node_hostname_address (
net_node_uuid TEXT NOT NULL,
address_uuid TEXT NOT NULL,
CONSTRAINT fk_net_node_hostname_address_net_node
FOREIGN KEY (net_node_uuid)
REFERENCES net_node (uuid),
CONSTRAINT fk_net_node_hostname_address_address
FOREIGN KEY (address_uuid)
REFERENCES hostname_address (uuid),
PRIMARY KEY (net_node_uuid, address_uuid)
);

-- v_address exposes ip and fqdn addresses as a single table.
-- Used for compatibility with the current core network model.
CREATE VIEW v_address AS
SELECT
ipa.address_value,
ipa.type_id,
ipa.config_type_id,
ipa.origin_id,
ipa.scope_id
FROM ip_address AS ipa
UNION
SELECT
fa.hostname AS address_value,
-- FQDN address type is always "hostname".
0 AS type_id,
-- FQDN address config type is always "manual".
3 AS config_type_id,
-- FQDN address doesn't have an origin.
null AS origin_id,
fa.scope_id
FROM fqdn_address AS fa;

CREATE TABLE ip_address_provider (
-- a provider-specific ID of the IP address.
provider_id TEXT NOT NULL PRIMARY KEY,
address_uuid TEXT NOT NULL,
CONSTRAINT fk_provider_ip_address_ip_address
FOREIGN KEY (address_uuid)
REFERENCES ip_address (uuid)
);

CREATE TABLE ip_address_subnet (
address_uuid TEXT NOT NULL PRIMARY KEY,
subnet_uuid TEXT NOT NULL,
CONSTRAINT fk_ip_address_subnet_subnet
FOREIGN KEY (subnet_uuid)
REFERENCES subnet (uuid),
CONSTRAINT fk_ip_address_subnet_ip_address
FOREIGN KEY (address_uuid)
REFERENCES ip_address (uuid)
);

CREATE TABLE ip_address_gateway (
address_uuid TEXT NOT NULL,
-- The IP address of the gateway this IP address's
-- device uses.
gateway_address TEXT NOT NULL,
-- true if that device/subnet is the default gateway
-- of the node.
is_default_gateway BOOLEAN DEFAULT false,
CONSTRAINT fk_ip_address_subnet_ip_address
FOREIGN KEY (address_uuid)
REFERENCES ip_address (uuid),
PRIMARY KEY (address_uuid, gateway_address)
);
25 changes: 25 additions & 0 deletions domain/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,35 @@ func (s *schemaSuite) TestModelTables(c *gc.C) {
"net_node",
"cloud_service",
"cloud_container",
"cloud_container_port",
"machine_cloud_instance",
"machine_cloud_instance_status",
"machine_cloud_instance_status_data",
"machine_lxd_profile",
"instance_tag",
"fqdn_address",
"net_node_fqdn_address",
"hostname_address",
"net_node_hostname_address",
"network_address_scope",

// Link layer device
"link_layer_device",
"link_layer_device_type",
"virtual_port_type",

// Network address
"net_node_ip_address",
"ip_address_scope",
"ip_address",
"ip_address_type",
"ip_address_origin",
"ip_address_config_type",
"ip_address_provider",
"ip_address_subnet",
"ip_address_gateway",
"ip_address_dns_search_domain",
"ip_address_dns_server_address",

// Unit
"unit",
Expand Down Expand Up @@ -462,6 +486,7 @@ func (s *schemaSuite) TestModelViews(c *gc.C) {
"v_charm_url",
"v_secret_permission",
"v_space_subnet",
"v_address",
)
c.Assert(readEntityNames(c, s.DB(), "view"), jc.SameContents, expected.SortedValues())
}
Expand Down
Loading

0 comments on commit 31ac3af

Please sign in to comment.