Skip to content

Commit c31ec1c

Browse files
authored
Merge pull request #1230 from Gijsreyn/gh-57/main/add-cidr-functions
Add `parseCidr()`, `cidrHost()`, and `cidrSubnet()` functions
2 parents 007090d + a048494 commit c31ec1c

File tree

12 files changed

+2059
-0
lines changed

12 files changed

+2059
-0
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ url = { version = "2.5" }
204204
urlencoding = { version = "2.1" }
205205
# dsc-lib
206206
which = { version = "8.0" }
207+
# dsc-lib
208+
ipnetwork = { version = "0.21" }
207209

208210
# build-only dependencies
209211
# dsc-lib, dsc-lib-registry, sshdconfig, tree-sitter-dscexpression, tree-sitter-ssh-server-config
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
---
2+
description: Reference for the 'cidrHost' DSC configuration document function
3+
ms.date: 11/03/2025
4+
ms.topic: reference
5+
title: cidrHost
6+
---
7+
8+
# cidrHost
9+
10+
## Synopsis
11+
12+
Calculates a host IP address within a CIDR network block.
13+
14+
## Syntax
15+
16+
```Syntax
17+
cidrHost(<cidrNotation>, <hostNumber>)
18+
```
19+
20+
## Description
21+
22+
The `cidrHost()` function calculates a specific host IP address within a given
23+
[CIDR][01] network block by adding a host number offset to the network address.
24+
This function is particularly useful for systematically assigning IP addresses
25+
to hosts, generating gateway addresses, or allocating IP addresses for network
26+
resources in infrastructure-as-code scenarios.
27+
28+
The host number is zero-indexed, where `0` represents the network address
29+
itself. For typical host assignments, start with `1` to get the first usable
30+
IP address in the network.
31+
32+
## Examples
33+
34+
### Example 1 - Calculate gateway address
35+
36+
Network configurations commonly use the first usable IP address as the gateway.
37+
This example calculates that address using host number `1`.
38+
39+
```yaml
40+
# cidrHost.example.1.dsc.config.yaml
41+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
42+
resources:
43+
- name: Gateway address
44+
type: Microsoft.DSC.Debug/Echo
45+
properties:
46+
output: "[cidrHost('10.0.1.0/24', 1)]"
47+
```
48+
49+
```bash
50+
dsc config get --file cidrHost.example.1.dsc.config.yaml
51+
```
52+
53+
```yaml
54+
results:
55+
- name: Gateway address
56+
type: Microsoft.DSC.Debug/Echo
57+
result:
58+
actualState:
59+
output: 10.0.1.1
60+
messages: []
61+
hadErrors: false
62+
```
63+
64+
### Example 2 - Assign multiple host addresses
65+
66+
This configuration demonstrates calculating host addresses for a subnet created
67+
with [`cidrSubnet()`][02], useful for assigning IP addresses to multiple servers
68+
or network devices.
69+
70+
```yaml
71+
# cidrHost.example.2.dsc.config.yaml
72+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
73+
parameters:
74+
baseNetwork:
75+
type: string
76+
defaultValue: 172.16.0.0/16
77+
subnetIndex:
78+
type: int
79+
defaultValue: 10
80+
resources:
81+
- name: Web server IPs
82+
type: Microsoft.DSC.Debug/Echo
83+
properties:
84+
output:
85+
subnet: "[cidrSubnet(parameters('baseNetwork'), 24, parameters('subnetIndex'))]"
86+
webServer1: "[cidrHost(cidrSubnet(parameters('baseNetwork'), 24, parameters('subnetIndex')), 10)]"
87+
webServer2: "[cidrHost(cidrSubnet(parameters('baseNetwork'), 24, parameters('subnetIndex')), 11)]"
88+
webServer3: "[cidrHost(cidrSubnet(parameters('baseNetwork'), 24, parameters('subnetIndex')), 12)]"
89+
```
90+
91+
```bash
92+
dsc config get --file cidrHost.example.2.dsc.config.yaml
93+
```
94+
95+
```yaml
96+
results:
97+
- name: Web server IPs
98+
type: Microsoft.DSC.Debug/Echo
99+
result:
100+
actualState:
101+
output:
102+
subnet: 172.16.10.0/24
103+
webServer1: 172.16.10.10
104+
webServer2: 172.16.10.11
105+
webServer3: 172.16.10.12
106+
messages: []
107+
hadErrors: false
108+
```
109+
110+
### Example 3 - Allocate IPs for network infrastructure
111+
112+
This configuration shows allocating specific IP addresses for various network
113+
infrastructure components within a subnet, demonstrating practical host number
114+
offsets for different device types.
115+
116+
```yaml
117+
# cidrHost.example.3.dsc.config.yaml
118+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
119+
parameters:
120+
networkCidr:
121+
type: string
122+
defaultValue: 192.168.100.0/24
123+
resources:
124+
- name: Network infrastructure IPs
125+
type: Microsoft.DSC.Debug/Echo
126+
properties:
127+
output:
128+
network: "[parameters('networkCidr')]"
129+
gateway: "[cidrHost(parameters('networkCidr'), 1)]"
130+
primaryDNS: "[cidrHost(parameters('networkCidr'), 2)]"
131+
secondaryDNS: "[cidrHost(parameters('networkCidr'), 3)]"
132+
loadBalancer: "[cidrHost(parameters('networkCidr'), 10)]"
133+
webServer1: "[cidrHost(parameters('networkCidr'), 20)]"
134+
webServer2: "[cidrHost(parameters('networkCidr'), 21)]"
135+
dbServer: "[cidrHost(parameters('networkCidr'), 50)]"
136+
```
137+
138+
```bash
139+
dsc config get --file cidrHost.example.3.dsc.config.yaml
140+
```
141+
142+
```yaml
143+
results:
144+
- name: Network infrastructure IPs
145+
type: Microsoft.DSC.Debug/Echo
146+
result:
147+
actualState:
148+
output:
149+
network: 192.168.100.0/24
150+
gateway: 192.168.100.1
151+
primaryDNS: 192.168.100.2
152+
secondaryDNS: 192.168.100.3
153+
loadBalancer: 192.168.100.10
154+
webServer1: 192.168.100.20
155+
webServer2: 192.168.100.21
156+
dbServer: 192.168.100.50
157+
messages: []
158+
hadErrors: false
159+
```
160+
161+
### Example 4 - IPv6 host address allocation
162+
163+
This configuration demonstrates calculating host addresses within an IPv6
164+
network, showing that the function supports both IPv4 and IPv6 address families.
165+
166+
```yaml
167+
# cidrHost.example.4.dsc.config.yaml
168+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
169+
parameters:
170+
ipv6Network:
171+
type: string
172+
defaultValue: 2001:db8::/64
173+
resources:
174+
- name: IPv6 host addresses
175+
type: Microsoft.DSC.Debug/Echo
176+
properties:
177+
output:
178+
network: "[parameters('ipv6Network')]"
179+
router: "[cidrHost(parameters('ipv6Network'), 1)]"
180+
server1: "[cidrHost(parameters('ipv6Network'), 10)]"
181+
server2: "[cidrHost(parameters('ipv6Network'), 11)]"
182+
```
183+
184+
```bash
185+
dsc config get --file cidrHost.example.4.dsc.config.yaml
186+
```
187+
188+
```yaml
189+
results:
190+
- name: IPv6 host addresses
191+
type: Microsoft.DSC.Debug/Echo
192+
result:
193+
actualState:
194+
output:
195+
network: 2001:db8::/64
196+
router: 2001:db8::1
197+
server1: 2001:db8::a
198+
server2: 2001:db8::b
199+
messages: []
200+
hadErrors: false
201+
```
202+
203+
## Parameters
204+
205+
### cidrNotation
206+
207+
The `cidrHost()` function expects the first parameter to be a string in valid
208+
CIDR notation format, including both an IP address and prefix length (e.g.,
209+
`10.0.0.0/16`).
210+
211+
```yaml
212+
Type: string
213+
Required: true
214+
MinimumCount: 1
215+
MaximumCount: 1
216+
```
217+
218+
### hostNumber
219+
220+
The second parameter specifies the host number offset from the network address.
221+
The value must be a non-negative integer within the valid range of the network.
222+
223+
- For a `/24` network (254 usable hosts), valid values are `0` to `255`
224+
- For a `/16` network (65,534 usable hosts), valid values are `0` to `65535`
225+
- Value `0` returns the network address itself
226+
- Value `1` typically returns the first usable host (often used for gateways)
227+
228+
The function raises an error if the host number exceeds the network capacity.
229+
230+
```yaml
231+
Type: integer
232+
Required: true
233+
MinimumCount: 1
234+
MaximumCount: 1
235+
```
236+
237+
## Output
238+
239+
The `cidrHost()` function returns a string containing the calculated IP address
240+
in standard notation (e.g., `10.0.1.15` for IPv4 or `2001:db8::a` for IPv6).
241+
242+
```yaml
243+
Type: string
244+
```
245+
246+
## Exceptions
247+
248+
The `cidrHost()` function raises errors for the following conditions:
249+
250+
- **Invalid CIDR notation**: When the CIDR string is malformed or missing the
251+
prefix length
252+
- **Host number out of range**: When the host number exceeds the maximum number
253+
of addresses in the network
254+
- **Invalid host number**: When the host number is negative
255+
256+
## Related functions
257+
258+
- [`cidrSubnet()`][02] - Creates a subnet from a larger CIDR block
259+
- [`parseCidr()`][03] - Parses CIDR notation and returns network details
260+
- [`add()`][04] - Adds two numbers together
261+
- [`parameters()`][05] - Retrieves parameter values
262+
263+
<!-- Link reference definitions -->
264+
[01]: https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
265+
[02]: ./cidrSubnet.md
266+
[03]: ./parseCidr.md
267+
[04]: ./add.md
268+
[05]: ./parameters.md

0 commit comments

Comments
 (0)