Adds policy and test for network isolation. This will not work on docker-desktop clusters.
This commit is contained in:
parent
533bf32577
commit
eae138f7fd
|
@ -128,9 +128,16 @@ namespace DistTestCore
|
||||||
return Get().CodexStarter.BringOnline((CodexSetup)codexSetup);
|
return Get().CodexStarter.BringOnline((CodexSetup)codexSetup);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BaseLog Log
|
protected void Log(string msg)
|
||||||
{
|
{
|
||||||
get { return Get().Log; }
|
TestContext.Progress.WriteLine(msg);
|
||||||
|
Get().Log.Log(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Debug(string msg)
|
||||||
|
{
|
||||||
|
TestContext.Progress.WriteLine(msg);
|
||||||
|
Get().Log.Debug(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestLifecycle Get()
|
private TestLifecycle Get()
|
||||||
|
|
|
@ -92,6 +92,10 @@ namespace DistTestCore
|
||||||
|
|
||||||
public ICodexSetup BringOffline()
|
public ICodexSetup BringOffline()
|
||||||
{
|
{
|
||||||
|
if (Group.Count() > 1) throw new InvalidOperationException("Codex-nodes that are part of a group cannot be " +
|
||||||
|
"individually shut down. Use 'BringOffline()' on the group object to stop the group. This method is only " +
|
||||||
|
"available for codex-nodes in groups of 1.");
|
||||||
|
|
||||||
return Group.BringOffline();
|
return Group.BringOffline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace KubernetesWorkflow
|
||||||
client = new K8sClient(cluster.GetK8sClientConfig());
|
client = new K8sClient(cluster.GetK8sClientConfig());
|
||||||
|
|
||||||
K8sTestNamespace = cluster.Configuration.K8sNamespacePrefix + testNamespace;
|
K8sTestNamespace = cluster.Configuration.K8sNamespacePrefix + testNamespace;
|
||||||
log.Debug($"'{K8sTestNamespace}'");
|
log.Debug($"Test namespace: '{K8sTestNamespace}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -121,6 +121,8 @@ namespace KubernetesWorkflow
|
||||||
};
|
};
|
||||||
client.Run(c => c.CreateNamespace(namespaceSpec));
|
client.Run(c => c.CreateNamespace(namespaceSpec));
|
||||||
WaitUntilNamespaceCreated();
|
WaitUntilNamespaceCreated();
|
||||||
|
|
||||||
|
CreatePolicy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsTestNamespaceOnline()
|
private bool IsTestNamespaceOnline()
|
||||||
|
@ -133,6 +135,67 @@ namespace KubernetesWorkflow
|
||||||
return client.Run(c => c.ListNamespace().Items.Any(n => n.Metadata.Name == name));
|
return client.Run(c => c.ListNamespace().Items.Any(n => n.Metadata.Name == name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CreatePolicy()
|
||||||
|
{
|
||||||
|
client.Run(c =>
|
||||||
|
{
|
||||||
|
var body = new V1NetworkPolicy
|
||||||
|
{
|
||||||
|
Metadata = new V1ObjectMeta
|
||||||
|
{
|
||||||
|
Name = "isolate-policy",
|
||||||
|
NamespaceProperty = K8sTestNamespace
|
||||||
|
},
|
||||||
|
Spec = new V1NetworkPolicySpec
|
||||||
|
{
|
||||||
|
PodSelector = new V1LabelSelector
|
||||||
|
{
|
||||||
|
MatchLabels = GetSelector()
|
||||||
|
},
|
||||||
|
PolicyTypes = new[]
|
||||||
|
{
|
||||||
|
"Ingress",
|
||||||
|
"Egress"
|
||||||
|
},
|
||||||
|
Ingress = new List<V1NetworkPolicyIngressRule>
|
||||||
|
{
|
||||||
|
new V1NetworkPolicyIngressRule
|
||||||
|
{
|
||||||
|
FromProperty = new List<V1NetworkPolicyPeer>
|
||||||
|
{
|
||||||
|
new V1NetworkPolicyPeer
|
||||||
|
{
|
||||||
|
NamespaceSelector = new V1LabelSelector
|
||||||
|
{
|
||||||
|
MatchLabels = GetMyNamespaceSelector()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Egress = new List<V1NetworkPolicyEgressRule>
|
||||||
|
{
|
||||||
|
new V1NetworkPolicyEgressRule
|
||||||
|
{
|
||||||
|
To = new List<V1NetworkPolicyPeer>
|
||||||
|
{
|
||||||
|
new V1NetworkPolicyPeer
|
||||||
|
{
|
||||||
|
NamespaceSelector = new V1LabelSelector
|
||||||
|
{
|
||||||
|
MatchLabels = GetMyNamespaceSelector()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
c.CreateNamespacedNetworkPolicy(body, K8sTestNamespace);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Deployment management
|
#region Deployment management
|
||||||
|
@ -192,12 +255,18 @@ namespace KubernetesWorkflow
|
||||||
return new Dictionary<string, string> { { "codex-test-node", "dist-test-" + workflowNumberSource.WorkflowNumber } };
|
return new Dictionary<string, string> { { "codex-test-node", "dist-test-" + workflowNumberSource.WorkflowNumber } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IDictionary<string, string> GetMyNamespaceSelector()
|
||||||
|
{
|
||||||
|
return new Dictionary<string, string> { { "name", "thatisincorrect" } };
|
||||||
|
}
|
||||||
|
|
||||||
private V1ObjectMeta CreateDeploymentMetadata()
|
private V1ObjectMeta CreateDeploymentMetadata()
|
||||||
{
|
{
|
||||||
return new V1ObjectMeta
|
return new V1ObjectMeta
|
||||||
{
|
{
|
||||||
Name = "deploy-" + workflowNumberSource.WorkflowNumber,
|
Name = "deploy-" + workflowNumberSource.WorkflowNumber,
|
||||||
NamespaceProperty = K8sTestNamespace
|
NamespaceProperty = K8sTestNamespace,
|
||||||
|
Labels = GetSelector()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,23 +4,20 @@ using Utils;
|
||||||
|
|
||||||
namespace Tests.BasicTests
|
namespace Tests.BasicTests
|
||||||
{
|
{
|
||||||
[Ignore("not a real test!")]
|
// Warning!
|
||||||
|
// This is a test to check network-isolation in the test-infrastructure.
|
||||||
|
// It requires parallelism(2) or greater to run.
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class NetworkIsolationTest : DistTest
|
public class NetworkIsolationTest : DistTest
|
||||||
{
|
{
|
||||||
private IOnlineCodexNode? node = null;
|
private IOnlineCodexNode? node = null;
|
||||||
|
|
||||||
// net isolation: only on real cluster?
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SetUpANodeAndWait()
|
public void SetUpANodeAndWait()
|
||||||
{
|
{
|
||||||
node = SetupCodexNode();
|
node = SetupCodexNode();
|
||||||
|
|
||||||
while (node != null)
|
Time.WaitUntil(() => node == null, TimeSpan.FromMinutes(5), TimeSpan.FromSeconds(5));
|
||||||
{
|
|
||||||
Time.Sleep(TimeSpan.FromSeconds(5));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -28,22 +25,21 @@ namespace Tests.BasicTests
|
||||||
{
|
{
|
||||||
var myNode = SetupCodexNode();
|
var myNode = SetupCodexNode();
|
||||||
|
|
||||||
while (node == null)
|
Time.WaitUntil(() => node != null, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(5));
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Time.Sleep(TimeSpan.FromSeconds(1));
|
myNode.ConnectToPeer(node!);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Good! This connection should be prohibited by the network isolation policy.
|
||||||
|
node = null;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
myNode.ConnectToPeer(node);
|
Assert.Fail("Connection could be established between two Codex nodes running in different namespaces. " +
|
||||||
|
"This may cause cross-test interference. Network isolation policy should be applied. Test infra failure.");
|
||||||
var testFile = GenerateTestFile(1.MB());
|
|
||||||
|
|
||||||
var contentId = node.UploadFile(testFile);
|
|
||||||
|
|
||||||
var downloadedFile = myNode.DownloadContent(contentId);
|
|
||||||
|
|
||||||
testFile.AssertIsEqual(downloadedFile);
|
|
||||||
|
|
||||||
node = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue