Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACI should use the configurable DNS server #127

Merged
merged 7 commits into from
Apr 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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