Skip to content

Commit 0f85901

Browse files
authored
Additional validations for DHCP enabled container host (#102)
* Additional validations for DHCP enabled container host * Removing debugs/comments * Update documentation * Minor change * Minor changes * Containerize Infra Params * Update SPEC.md
1 parent 2137a67 commit 0f85901

File tree

8 files changed

+166
-5
lines changed

8 files changed

+166
-5
lines changed

scripts/autogencniconf/SPEC.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
- [Appendix: Examples](#appendix-examples)
1717
- [Basic Conf](#basic-conf)
1818
- [Conf with additional policies](#conf-with-additional-policies)
19-
- [Sample auto-generated CNI configuration](#sample-auto-generated-cni-configuration)
19+
- [Conf with DHCP parameters](#conf-with-dhcp-parameters)
20+
- [Sample auto-generated CNI configuration](#sample-auto-generated-cni-configuration)
2021

2122
## Version
2223

@@ -30,7 +31,7 @@ Released versions of the spec are available as Git tags.
3031

3132
| tag | spec permalink | major changes |
3233
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | --------------------------------- |
33-
| [`spec-v1.0.0`](https://github.com/microsoft/windows-container-networking/cni/releases/tag/spec-v1.0.0) | [spec at v1.0.0](https://github.com/microsoft/windows-container-networking/cni/blob/spec-v1.0.0/SPEC.md) | Removed non-list configurations; removed `version` field of `interfaces` array |
34+
| [`spec-v1.0.0`](https://github.com/microsoft/windows-container-networking/cni/releases/tag/spec-v1.0.0) | [spec at v1.0.0](https://github.com/microsoft/windows-container-networking/cni/blob/spec-v1.0.0/SPEC.md) | Initial draft |
3435

3536
*Do not rely on these tags being stable. In the future, we may change our mind about which particular commit is the right marker for a given historical spec version.*
3637

@@ -76,7 +77,10 @@ Below sections specify the JSON format that needs to be passed after [encoding](
7677
- `LocalEndpoint` (string): IP Address of the local endpoint. Used to configure default policies for the endpoint. This parameter is *MANDATORY*.
7778
- `InfraPrefix` (string): CIDR of the management network of the underlying node. Used to configure default policies for the network. This parameter is *MANDATORY*.
7879
- `AddditionalPolicies` (dictionary): Defined [here](#configure-additional-policies). This parameter is *NOT MANDATORY*.
79-
### Configure Additional Policies
80+
- `InfraParams` (dictionary): This parameter contains configurations that are not translated into any CNI conf field, it is only meaningful to the infrastructure layer. This parameter is *NOT MANDATORY*.
81+
- `DhcpEnabled` (boolean): Set to true if the container host management interface is expected to have a DHCP leased IP. This parameter is *NOT MANDATORY*.
82+
- `DhcpCheckTimeout` (integer): Wait for this time interval in seconds for the DHCP IP to get assigned before creating the HNS Network and generating the CNI conf. This parameter is *NOT MANDATORY*. This parameter can only be set if 'DhcpEnabled' field is set to true.
83+
### Configure Additional Policies
8084
#### ACL Policy
8185
There are few system-defined default ACL policies. Users can configure additional ACL polices with below parameters.
8286
- `RemoteAddresses` (string): This parameter is *NOT MANDATORY*.
@@ -91,8 +95,8 @@ There are few system-defined default ACL policies. Users can configure additiona
9195
#### OutBound NAT Policy
9296
- `Exceptions` (string[]): List of IP Addresses/CIDRs to allow NATed outbound traffic. This parameter is *MANDATORY*.
9397
#### SDNRoute Policy
94-
- `DestinationPrefix` (string): .This parameter is *MANDATORY*.
95-
- `NeedEncap` (bool): . This parameter is *MANDATORY*.
98+
- `DestinationPrefix` (string): This parameter is *MANDATORY*.
99+
- `NeedEncap` (bool): This parameter is *MANDATORY*.
96100
## Appendix: Examples
97101
### Basic Conf
98102
```jsonc
@@ -144,6 +148,18 @@ There are few system-defined default ACL policies. Users can configure additiona
144148
]
145149
}
146150
```
151+
### Conf with DHCP parameters
152+
```jsonc
153+
{
154+
"Name": "azure-cni",
155+
"Type": "sdnbridge",
156+
"Subnet": "192.168.0.0/24",
157+
"InfraPrefix": "172.16.0.0/24",
158+
"Gateway": "192.168.0.2",
159+
"DnsServers": "8.8.8.8",
160+
"InfraParams" : { "DhcpEnabled": true, "DhcpCheckTimeout": 90 }
161+
}
162+
```
147163
### Sample auto-generated CNI configuration
148164
```jsonc
149165
VERBOSE: Generated CNI conf: .\cni.conf

scripts/autogencniconf/generateCNIConfig.ps1

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ set-variable -name ACL_POLICY -value ([string]"ACL") -Scope Script
5555
set-variable -name DEFAULT_PRIORITY -value ([string]"-1") -Scope Script # Used to help in sorting the policies based on priority even if priority is not specified by user
5656
set-variable -name USER_POLICY_PRIO_START -value ([int]3000) -Scope Script
5757
set-variable -name USER_POLICY_PRIO_END -value ([int]8000) -Scope Script
58+
set-variable -name DHCP_CHECK_TIMEOUT_MIN -value ([int]60) -Scope Script
59+
set-variable -name DHCP_CHECK_TIMEOUT_MAX -value ([int]600) -Scope Script
5860

5961
enum OptionalKeysFlag {
6062
NoOptKeys = 1
@@ -81,6 +83,11 @@ class Policy {
8183
}
8284
}
8385

86+
class InfraParams {
87+
[bool] $DhcpEnabled
88+
[int] $DhcpCheckTimeout
89+
}
90+
8491
class CniArgs {
8592
[string] $Name
8693
[string] $Type
@@ -92,6 +99,7 @@ class CniArgs {
9299
[string[]] $DnsServers
93100
[Policy[]] $AdditionalPolicies
94101
[bool] $SkipDefaultPolicies # Undocumented parameter to disable system policies
102+
[InfraParams] $InfraParams
95103

96104
CniArgs([System.Object] $cniArgs) {
97105
# Mandatory Parameters
@@ -106,6 +114,26 @@ class CniArgs {
106114
# Optional Parameters
107115
if ($cniArgs.psobject.Properties.name.Contains('Version')) {$this.Version = $cniArgs.Version} else {$this.Version = $script:DEFAULT_CNI_VERSION}
108116
if ($cniArgs.psobject.Properties.name.Contains('SkipDefaultPolicies')) {$this.SkipDefaultPolicies = $true} else {$this.SkipDefaultPolicies = $false}
117+
if ($cniArgs.psobject.Properties.name.Contains('InfraParams')) {
118+
$cniArgsInfraParams = $cniArgs.InfraParams
119+
$this.InfraParams = [InfraParams]::new()
120+
if ($cniArgsInfraParams.psobject.Properties.name.Contains('DhcpEnabled')) {$this.InfraParams.DhcpEnabled = $cniArgsInfraParams.DhcpEnabled}
121+
if ($this.InfraParams.DhcpEnabled -eq $true) {
122+
$this.InfraParams.DhcpCheckTimeout = $script:DHCP_CHECK_TIMEOUT_MIN # Default value of 60 secs, based on RFC 1541
123+
if ($cniArgsInfraParams.psobject.Properties.name.Contains('DhcpCheckTimeout')) {
124+
if((-not (($cniArgsInfraParams.DhcpCheckTimeout -ge $script:DHCP_CHECK_TIMEOUT_MIN) -and ($cniArgsInfraParams.DhcpCheckTimeout -le $script:DHCP_CHECK_TIMEOUT_MAX))) -or (($cniArgsInfraParams.DhcpCheckTimeout % 10) -ne 0)) {
125+
Write-Verbose -Message ("DHCP Check timeout should be a multiple of 10 and have a value between {0} - {1}. Invalid dhcp check timeout parameter: {2}" -f $script:DHCP_CHECK_TIMEOUT_MIN, $script:DHCP_CHECK_TIMEOUT_MAX, $cniArgsInfraParams.DhcpCheckTimeout)
126+
throw ("Invalid DHCP Check timeout parameter: {0}" -f $cniArgsInfraParams.DhcpCheckTimeout)
127+
}
128+
$this.InfraParams.DhcpCheckTimeout = $cniArgsInfraParams.DhcpCheckTimeout
129+
}
130+
} else {
131+
if ($cniArgsInfraParams.psobject.Properties.name.Contains('DhcpCheckTimeout')) {
132+
Write-Verbose -Message ("DHCP Check timeout should be a configured only when DhcpEnabled is set.")
133+
throw "Invalid DHCP Check timeout parameter should be configured only when DhcpEnabled parameter is set. Missing parameter DhcpEnabled."
134+
}
135+
}
136+
}
109137
if ($cniArgs.psobject.Properties.name.Contains('AdditionalPolicies')) {
110138
for($i=0; $i -lt $cniArgs.AdditionalPolicies.length; $i++) {
111139
# Following constraints are ensured for policy priorities (HNS supports priorities between 100-65500 for ACLs)
@@ -323,3 +351,5 @@ Remove-Variable -name DEFAULT_PRIORITY -Scope Script
323351
Remove-Variable -name ACL_POLICY -Scope Script
324352
Remove-Variable -name USER_POLICY_PRIO_START -Scope Script
325353
Remove-Variable -name USER_POLICY_PRIO_END -Scope Script
354+
Remove-Variable -name DHCP_CHECK_TIMEOUT_MIN -Scope Script
355+
Remove-Variable -name DHCP_CHECK_TIMEOUT_MAX -Scope Script

scripts/autogencniconf/test/autogencniconf_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,19 @@ var _ = BeforeSuite(func() {
4949
Expect(scriptPath).To(BeAnExistingFile())
5050
})
5151

52+
53+
5254
var _ = Describe("Autogen CNI conf Tests", func() {
5355

56+
AfterEach(func() {
57+
// Remove the cni conf if generated after every test case
58+
_, err := os.Stat(cniConfPath)
59+
if err == nil {
60+
err = os.Remove(cniConfPath)
61+
Expect(err).NotTo(HaveOccurred(), "cni conf file [%v] deletion failed with err [%s]", cniConfPath, err)
62+
}
63+
})
64+
5465
// Test Case 1
5566
It("Verifies that error is thrown if input json is invalid", func() {
5667
cniArgs := getEncodedCniArgs("tc1_input.json")
@@ -232,4 +243,58 @@ var _ = Describe("Autogen CNI conf Tests", func() {
232243
Expect(cniConfPath).NotTo(BeAnExistingFile())
233244
})
234245
})
246+
247+
// Test Case 8
248+
When("Setting up networking for a DHCP enabled host", func() {
249+
250+
It("Verifies lower limit of the DHCP check timeout is honored", func() {
251+
cniArgs := getEncodedCniArgs("tc8a_input.json")
252+
Expect(cniArgs).NotTo(BeEmpty())
253+
254+
cmd := exec.Command("powershell", scriptPath, "-CniArgs", cniArgs, "-CniConfPath", cniConfPath)
255+
out, err := cmd.CombinedOutput()
256+
Expect(err).To(HaveOccurred(), "cmd [%s] failed with error [%v]. output is [%s]", cmd, err, out)
257+
Expect(cniConfPath).NotTo(BeAnExistingFile())
258+
})
259+
260+
It("Verifies higher limit of the DHCP check timeout is honored", func() {
261+
cniArgs := getEncodedCniArgs("tc8b_input.json")
262+
Expect(cniArgs).NotTo(BeEmpty())
263+
264+
cmd := exec.Command("powershell", scriptPath, "-CniArgs", cniArgs, "-CniConfPath", cniConfPath)
265+
out, err := cmd.CombinedOutput()
266+
Expect(err).To(HaveOccurred(), "cmd [%s] failed with error [%v]. output is [%s]", cmd, err, out)
267+
Expect(cniConfPath).NotTo(BeAnExistingFile())
268+
})
269+
270+
It("Verifies the DHCP check timeout is a multiple of 10", func() {
271+
cniArgs := getEncodedCniArgs("tc8c_input.json")
272+
Expect(cniArgs).NotTo(BeEmpty())
273+
274+
cmd := exec.Command("powershell", scriptPath, "-CniArgs", cniArgs, "-CniConfPath", cniConfPath)
275+
out, err := cmd.CombinedOutput()
276+
Expect(err).To(HaveOccurred(), "cmd [%s] failed with error [%v]. output is [%s]", cmd, err, out)
277+
Expect(cniConfPath).NotTo(BeAnExistingFile())
278+
})
279+
280+
It("Verifies default DHCP check timeout is used if the parameter is missing", func() {
281+
cniArgs := getEncodedCniArgs("tc8d_input.json")
282+
Expect(cniArgs).NotTo(BeEmpty())
283+
284+
cmd := exec.Command("powershell", scriptPath, "-CniArgs", cniArgs, "-CniConfPath", cniConfPath)
285+
out, err := cmd.CombinedOutput()
286+
Expect(err).NotTo(HaveOccurred(), "cmd [%s] failed with error [%v]. output is [%s]", cmd, err, out)
287+
Expect(cniConfPath).To(BeAnExistingFile())
288+
})
289+
290+
It("Verifies DHCP check timeout is honored only if DhcpEnabled parameter is set", func() {
291+
cniArgs := getEncodedCniArgs("tc8e_input.json")
292+
Expect(cniArgs).NotTo(BeEmpty())
293+
294+
cmd := exec.Command("powershell", scriptPath, "-CniArgs", cniArgs, "-CniConfPath", cniConfPath)
295+
out, err := cmd.CombinedOutput()
296+
Expect(err).To(HaveOccurred(), "cmd [%s] failed with error [%v]. output is [%s]", cmd, err, out)
297+
Expect(cniConfPath).NotTo(BeAnExistingFile())
298+
})
299+
})
235300
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Name": "azure-cni",
3+
"Type": "sdnbridge",
4+
"Subnet": "192.168.0.0/24",
5+
"Gateway": "192.168.0.2",
6+
"InfraPrefix": "10.0.0.0/24",
7+
"DnsServers": ["168.63.129.16"],
8+
"ManagementIp": "10.0.0.10",
9+
"InfraParams": { "DhcpEnabled": true, "DhcpCheckTimeout": 5 }
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Name": "azure-cni",
3+
"Type": "sdnbridge",
4+
"Subnet": "192.168.0.0/24",
5+
"Gateway": "192.168.0.2",
6+
"InfraPrefix": "10.0.0.0/24",
7+
"DnsServers": ["168.63.129.16"],
8+
"ManagementIp": "10.0.0.10",
9+
"InfraParams": { "DhcpEnabled": true, "DhcpCheckTimeout": 800 }
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Name": "azure-cni",
3+
"Type": "sdnbridge",
4+
"Subnet": "192.168.0.0/24",
5+
"Gateway": "192.168.0.2",
6+
"InfraPrefix": "10.0.0.0/24",
7+
"DnsServers": ["168.63.129.16"],
8+
"ManagementIp": "10.0.0.10",
9+
"InfraParams": { "DhcpEnabled": true, "DhcpCheckTimeout": 65 }
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Name": "azure-cni",
3+
"Type": "sdnbridge",
4+
"Subnet": "192.168.0.0/24",
5+
"Gateway": "192.168.0.2",
6+
"InfraPrefix": "10.0.0.0/24",
7+
"DnsServers": ["168.63.129.16"],
8+
"ManagementIp": "10.0.0.10",
9+
"InfraParams": { "DhcpEnabled": true }
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Name": "azure-cni",
3+
"Type": "sdnbridge",
4+
"Subnet": "192.168.0.0/24",
5+
"Gateway": "192.168.0.2",
6+
"InfraPrefix": "10.0.0.0/24",
7+
"DnsServers": ["168.63.129.16"],
8+
"ManagementIp": "10.0.0.10",
9+
"InfraParams": { "DhcpCheckTimeout": 80 }
10+
}

0 commit comments

Comments
 (0)