Skip to content

Commit

Permalink
ACI should use the configurable DNS server (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
sparsick authored Apr 15, 2022
1 parent 784a6a7 commit a52ede1
Show file tree
Hide file tree
Showing 13 changed files with 229 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public AciContainerTemplate(String name,
String memory) {
this.name = name;
this.label = label;
this.image = image;
this.image = image.trim();
this.osType = osType;
this.command = command;
this.rootFs = rootFs;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.microsoft.jenkins.containeragents.aci;

import com.microsoft.jenkins.containeragents.aci.dns.AciDnsConfig;
import hudson.Extension;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
Expand All @@ -13,6 +14,8 @@ public class AciPrivateIpAddress extends AbstractDescribableImpl<AciPrivateIpAdd

private String resourceGroup;

private AciDnsConfig dnsConfig;

@DataBoundConstructor
public AciPrivateIpAddress(String vnet, String subnet) {
this.vnet = vnet;
Expand All @@ -31,12 +34,21 @@ public String getResourceGroup() {
return resourceGroup;
}


@DataBoundSetter
public void setResourceGroup(String resourceGroup) {
this.resourceGroup = resourceGroup;
}

public AciDnsConfig getDnsConfig() {
return dnsConfig;
}

@DataBoundSetter
public void setDnsConfig(AciDnsConfig dnsConfig) {
this.dnsConfig = dnsConfig;
}


@Extension
public static class DescriptorImpl extends Descriptor<AciPrivateIpAddress> {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.microsoft.jenkins.containeragents.aci.dns;

import hudson.Extension;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class AciDnsConfig extends AbstractDescribableImpl<AciDnsConfig> {

private List<AciDnsServer> dnsServers = new ArrayList<>();

@DataBoundConstructor
public AciDnsConfig() {
}

public List<AciDnsServer> getDnsServers() {
return dnsServers;
}

@DataBoundSetter
public void setDnsServers(List<AciDnsServer> dnsServers) {
this.dnsServers = dnsServers.stream()
.filter(aciDnsServer -> !aciDnsServer.getAddress().isEmpty())
.collect(Collectors.toList());
}


@Extension
public static class DescriptorImpl extends Descriptor<AciDnsConfig> {

@Override
public String getDisplayName() {
return "Aci DNS Config";
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.microsoft.jenkins.containeragents.aci.dns;

import hudson.Extension;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import org.kohsuke.stapler.DataBoundConstructor;

public class AciDnsServer extends AbstractDescribableImpl<AciDnsServer> {

private String address;

@DataBoundConstructor
public AciDnsServer(String address) {
this.address = address;
}

public String getAddress() {
return address;
}

@Extension
public static class DescriptorImpl extends Descriptor<AciDnsServer> {

@Override
public String getDisplayName() {
return "Aci DNS Server";
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.microsoft.jenkins.containeragents.aci.AciPort;
import com.microsoft.jenkins.containeragents.aci.AciPrivateIpAddress;
import com.microsoft.jenkins.containeragents.aci.AciService;
import com.microsoft.jenkins.containeragents.aci.dns.AciDnsServer;
import com.microsoft.jenkins.containeragents.aci.volumes.AzureFileVolume;
import com.microsoft.jenkins.containeragents.util.AzureContainerUtils;
import com.microsoft.jenkins.containeragents.util.Constants;
Expand Down Expand Up @@ -104,11 +105,30 @@ public AciDeploymentTemplate buildDeploymentTemplate(AciCloud cloud, AciContaine
}

addSubnetIds(tmp, mapper, privateIpAddress);
addDnsConfig(tmp, mapper, privateIpAddress);

return new AciDeploymentTemplate(tmp, parameters);
}
}

private void addDnsConfig(JsonNode tmp, ObjectMapper mapper, AciPrivateIpAddress privateIpAddress) {
if (privateIpAddress == null || privateIpAddress.getDnsConfig() == null
|| privateIpAddress.getDnsConfig().getDnsServers().isEmpty()) {
return;
}
List<AciDnsServer> dnsServerNames = privateIpAddress.getDnsConfig().getDnsServers();
ArrayNode dnsServerArray = mapper.createArrayNode();
dnsServerNames.forEach(dnsServer -> dnsServerArray.add(dnsServer.getAddress()));

ObjectNode dnsServersNode = mapper.createObjectNode();
dnsServersNode.set("nameServers", dnsServerArray);

ArrayNode resourcesArray = (ArrayNode) tmp.get("resources");
ObjectNode containerGroupItem = (ObjectNode) resourcesArray.get(0);
ObjectNode propertiesNode = (ObjectNode) containerGroupItem.get("properties");
propertiesNode.set("dnsConfig", dnsServersNode);
}

private void addSubnetIds(JsonNode tmp, ObjectMapper mapper, AciPrivateIpAddress privateIpAddress) {
if (privateIpAddress == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@
<f:entry title="Name of the subnet" >
<f:textbox field="subnet" />
</f:entry>

<f:optionalProperty field="dnsConfig" title="DNS Configuration" />

</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div>
Select if the container instance should use a specific DNS configuration. (See also
<a href="https://docs.microsoft.com/en-us/azure/templates/microsoft.containerinstance/containergroups?tabs=json#dnsconfiguration">
Azure documentation about Container Group
</a>).
<p>
Important: Currently, only a list of dns server name is supported.
</p>

</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">

<f:entry>
<f:repeatable field="dnsServerNames" minimum="0">
<f:entry title="DNS server name" field="dnsServer">
<f:textbox/>
</f:entry>
</f:repeatable>
</f:entry>


</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;

public class JCasCTest extends RoundTripAbstractTest {
Expand All @@ -24,6 +26,9 @@ protected void assertConfiguredAsExpected(RestartableJenkinsRule j, String confi
assertThat(aciContainerTemplate.getPrivateIpAddress(), notNullValue());
assertThat(aciContainerTemplate.getPrivateIpAddress().getVnet(), equalTo("vnet"));
assertThat(aciContainerTemplate.getPrivateIpAddress().getSubnet(), equalTo("subnet"));
assertThat(aciContainerTemplate.getPrivateIpAddress().getResourceGroup(), equalTo("rg"));
assertThat(aciContainerTemplate.getPrivateIpAddress().getDnsConfig(), notNullValue());
assertThat(aciContainerTemplate.getPrivateIpAddress().getDnsConfig().getDnsServers(), not(empty()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.microsoft.jenkins.containeragents.aci;

import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;


public class AciContainerTemplateTest {

@Test
public void ignoreWhitespaceInImageName() {
AciContainerTemplate templateUnderTest = new AciContainerTemplate("name", "label", 100,
"osType", " image ", "command" , "rootFs", null, null,
null, null, null, "cpu", "memory");

assertThat(templateUnderTest.getImage(), equalTo("image"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.microsoft.jenkins.containeragents.aci.dns;


import org.junit.Test;

import java.util.Arrays;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;

public class AciDnsConfigTest {

@Test
public void emptyDnServerNamesAreIgnored(){
AciDnsConfig configUnderTest = new AciDnsConfig();
configUnderTest.setDnsServers(Arrays.asList(new AciDnsServer("dnsServerName"), new AciDnsServer("")));

assertThat(configUnderTest.getDnsServers(), hasSize(1));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
import com.microsoft.jenkins.containeragents.aci.AciCloud;
import com.microsoft.jenkins.containeragents.aci.AciContainerTemplate;
import com.microsoft.jenkins.containeragents.aci.AciPrivateIpAddress;
import com.microsoft.jenkins.containeragents.aci.dns.AciDnsConfig;
import com.microsoft.jenkins.containeragents.aci.dns.AciDnsServer;
import hudson.slaves.RetentionStrategy;
import hudson.slaves.SlaveComputer;
import io.jenkins.plugins.util.JenkinsFacade;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Arrays;

import static java.util.Collections.emptyList;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -85,6 +88,50 @@ public void templateWithVnetAndOwnButEmptyRg() throws IOException {
assertThat(aciDeploymentTemplate.deploymentTemplateAsString(), containsString("\"subnetIds\":"));
}

@Test
public void templateWithVnetAndDnsConfig() throws IOException {
AciCloud cloud = new AciCloud("testcloud", "credentialId", "resourceGroup", emptyList());

AciContainerTemplate template = new AciContainerTemplate("containerName", "label", 100, "linux", "helloworld", "command", "rootFs", emptyList(), emptyList(), emptyList(), emptyList(), new RetentionStrategy.Always(), "cpu", "memory" );
AciPrivateIpAddress privateIpAddress = new AciPrivateIpAddress("vnet", "subnet");
AciDnsConfig dnsConfig = new AciDnsConfig();
dnsConfig.setDnsServers(Arrays.asList(new AciDnsServer("dnsName")));
privateIpAddress.setDnsConfig(dnsConfig);
template.setPrivateIpAddress(privateIpAddress);

AciDeploymentTemplateBuilder.AciDeploymentTemplate aciDeploymentTemplate = builderUnderTest.buildDeploymentTemplate(cloud, template, agentMock);

assertThat(aciDeploymentTemplate.deploymentTemplateAsString(), containsString("\"dnsConfig\":"));
assertThat(aciDeploymentTemplate.deploymentTemplateAsString(), containsString("\"nameServers\":[\"dnsName\"]"));
}

@Test
public void templateWithVnetAndDnsConfigWithoutDnsServer() throws IOException {
AciCloud cloud = new AciCloud("testcloud", "credentialId", "resourceGroup", emptyList());

AciContainerTemplate template = new AciContainerTemplate("containerName", "label", 100, "linux", "helloworld", "command", "rootFs", emptyList(), emptyList(), emptyList(), emptyList(), new RetentionStrategy.Always(), "cpu", "memory" );
AciPrivateIpAddress privateIpAddress = new AciPrivateIpAddress("vnet", "subnet");
privateIpAddress.setDnsConfig(new AciDnsConfig());
template.setPrivateIpAddress(privateIpAddress);

AciDeploymentTemplateBuilder.AciDeploymentTemplate aciDeploymentTemplate = builderUnderTest.buildDeploymentTemplate(cloud, template, agentMock);

assertThat(aciDeploymentTemplate.deploymentTemplateAsString(), not(containsString("\"dnsConfig\":")));
}


@Test
public void templateWithVnetWithoutDnsConfig() throws IOException {
AciCloud cloud = new AciCloud("testcloud", "credentialId", "resourceGroup", emptyList());

AciContainerTemplate template = new AciContainerTemplate("containerName", "label", 100, "linux", "helloworld", "command", "rootFs", emptyList(), emptyList(), emptyList(), emptyList(), new RetentionStrategy.Always(), "cpu", "memory" );
template.setPrivateIpAddress(new AciPrivateIpAddress("vnet", "subnet"));

AciDeploymentTemplateBuilder.AciDeploymentTemplate aciDeploymentTemplate = builderUnderTest.buildDeploymentTemplate(cloud, template, agentMock);

assertThat(aciDeploymentTemplate.deploymentTemplateAsString(), not(containsString("\"dnsConfig\":")));
}

@Test
public void templateWithoutVnet() throws IOException {
AciCloud cloud = new AciCloud("testcloud", "credentialId", "resourceGroup", emptyList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ jenkins:
privateIpAddress:
subnet: "subnet"
vnet: "vnet"
resourceGroup: "rg"
dnsConfig:
dnsServers:
- address: "dnsServerAddress"
retentionStrategy: "containerOnce"
rootFs: "/home/jenkins"
timeout: 10

0 comments on commit a52ede1

Please sign in to comment.