public static V1PersistentVolumeClaim CreateVolumeClaim(string serverName) { string storageClassName = "azurefile"; var label = serverName + "-storage"; var claim = new V1PersistentVolumeClaim { ApiVersion = "v1", Kind = "PersistentVolumeClaim", Metadata = new V1ObjectMeta { Name = label }, Spec = new V1PersistentVolumeClaimSpec { AccessModes = new List <string> { "ReadWriteMany" }, StorageClassName = storageClassName, Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { { "storage", new ResourceQuantity(30 + "Gi") } } } } }; return(claim); }
public void ReferenceComparisonTest() { var pvc1 = new V1PersistentVolumeClaim(); var pvc2 = pvc1; Assert.True(comparer.Equals(pvc1, pvc2)); Assert.False(comparer.Equals(null, pvc2)); Assert.False(comparer.Equals(pvc1, null)); }
static (V1PersistentVolumeClaim, V1PersistentVolumeClaim) MakeIdenticalPVCs() { var x = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = "device1", [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname" }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", AccessModes = new List <string> { "ReadOnce" }, Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; var y = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = "device1", [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname" }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", AccessModes = new List <string> { "ReadOnce" }, Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; return(x, y); }
public void SuccessComparisonTest() { var x = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = "device1", [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname" }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", AccessModes = new List <string> { "ReadOnce" }, Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; var y = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = "device1", [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname" }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", AccessModes = new List <string> { "ReadOnce" }, Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; Assert.True(comparer.Equals(x, y)); }
bool IsCreatedByController(V1PersistentVolumeClaim claim) { var labels = claim.Metadata?.Labels; if (labels == null) { return(false); } if (!labels.ContainsKey(KubernetesConstants.K8sEdgeDeviceLabel)) { return(false); } return(labels[KubernetesConstants.K8sEdgeDeviceLabel] == KubeUtils.SanitizeLabelValue(this.resourceName.DeviceId)); }
public void IgnoreOtherMetadataTest() { var pvcWithOwnerRefMetadata = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = KubeUtils.SanitizeLabelValue("device1"), [KubernetesConstants.K8sEdgeHubNameLabel] = KubeUtils.SanitizeLabelValue("hostname") }, ownerReferences: new List <V1OwnerReference> { new V1OwnerReference("v1", name: "iotedged", kind: "Deployment", uid: "123") }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; var pvcWithoutOwnerRefMetadata = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = KubeUtils.SanitizeLabelValue("device1"), [KubernetesConstants.K8sEdgeHubNameLabel] = KubeUtils.SanitizeLabelValue("hostname") }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; Assert.False(comparer.Equals(pvcWithOwnerRefMetadata, pvcWithoutOwnerRefMetadata)); }
public SampleAppsFixture() { BuildNumber = Environment.GetEnvironmentVariable(BUILD_NUMBER_VAR) ?? Guid.NewGuid().ToString(); BuildNumber = BuildNumber.Replace('.', '_'); // Dots are invalid in Kubernetes service names var storageKey = Environment.GetEnvironmentVariable(STORAGE_KEY_VAR); Console.WriteLine("Using storage key \"{0}...\" from environment variable \"{1}\"", storageKey.Substring(0, 4), STORAGE_KEY_VAR); FolderName = "SampleApps-" + BuildNumber; fileShare = CloudStorageAccount.Parse($"DefaultEndpointsProtocol=https;AccountName={STORAGE_ACCOUNT_NAME};AccountKey={storageKey};EndpointSuffix=core.windows.net") .CreateCloudFileClient() .GetShareReference(STORAGE_SHARE_NAME); UploadToFileShare(fileShare, FolderName); KubernetesClientConfiguration config; string kubeConfig = Environment.GetEnvironmentVariable(KUBECONFIG_VAR); if (string.IsNullOrEmpty(kubeConfig)) { config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); } else { byte[] configByteArray = System.Text.Encoding.UTF8.GetBytes(kubeConfig); using (var stream = new MemoryStream(configByteArray)) { config = KubernetesClientConfiguration.BuildConfigFromConfigFile(stream); } } Client = new Kubernetes(config); // Create a PV for our Azure File share and a corresponding claim if they don't already exist // If these fail, make sure that they don't already exist in the cluster: `kubectl delete -n default pvc,pv --all` storage = Client.CreatePersistentVolume(Specs.BuildVolume.GetSpec(VOLUME_NAME, STORAGE_REQUESTED_CAPACITY, STORAGE_SHARE_NAME)); storageClaim = Client.CreateNamespacedPersistentVolumeClaim(Specs.BuildVolumeClaim.GetSpec(STORAGE_REQUESTED_CAPACITY), NAMESPACE); Console.WriteLine("Created PersistentVolume and corresponding PersistentVolumeClaim"); // Create the build pod var podSpec = Specs.BuildPod.GetSpec(BUILD_POD_NAME, VOLUME_NAME, storageClaim.Metadata.Name); BuildPod = k8sHelpers.CreatePodAndWait(Client, podSpec, NAMESPACE, k8sHelpers.IsPodRunning).Result; Console.WriteLine("Build pod is up & running"); }
public void NoAccessModeTest() { var x = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = KubeUtils.SanitizeLabelValue("device1"), [KubernetesConstants.K8sEdgeHubNameLabel] = KubeUtils.SanitizeLabelValue("hostname") }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; var y = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = KubeUtils.SanitizeLabelValue("device1"), [KubernetesConstants.K8sEdgeHubNameLabel] = KubeUtils.SanitizeLabelValue("hostname") }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; Assert.False(comparer.Equals(x, y)); }
public static void UpdatePvc(V1PersistentVolumeClaim pvc) { Log.LogInformation((int)EventIds.UpdatePvc, $"Update PVC {pvc.Metadata.Name}"); }
internal static void CreatePvc(V1PersistentVolumeClaim pvc) { Log.LogInformation((int)EventIds.CreatePvc, $"Create PVC {pvc.Metadata.Name}"); }
public async Task CsiAzureDiskTest() { STEP("Init Environment and attach disk via csi plugins"); var pvcName = "pvc1"; var pvc = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta { Name = pvcName, }, Spec = new V1PersistentVolumeClaimSpec { AccessModes = new List <string> { "ReadWriteOnce" }, StorageClassName = "azuredisk-csi", Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("2Gi"), }, }, }, }; var pod = new V1Pod { Metadata = new V1ObjectMeta { Name = "claim", }, Spec = new V1PodSpec { RestartPolicy = "Never", Containers = new List <V1Container> { new V1Container { Image = "busybox", Args = new List <string> { "touch", "/af-vol/temp" }, Name = "test", VolumeMounts = new List <V1VolumeMount> { new V1VolumeMount { MountPath = "/af-vol", Name = "af-pvc", } } } }, Volumes = new List <V1Volume> { new V1Volume { Name = "af-pvc", PersistentVolumeClaim = new V1PersistentVolumeClaimVolumeSource { ClaimName = pvcName }, } } } }; var diskListOld = await azureDiskClient.GetDiskNameList(); await tkc.EnsureNamespace(); await tkc.CreatePvc(pvc); await tkc.CreatePod(pod); Assert.True(await tkc.WaitPodCompleted(pod.Metadata.Name), "Pod construction failed"); STEP("Geting the name of the new disk"); var diskListNew = await azureDiskClient.GetDiskNameList(); Assert.Equal(diskListOld.Count + 1, diskListNew.Count); string diskNewName = ""; foreach (var diskNew in diskListNew) { if (!diskListOld.Contains(diskNew)) { diskNewName = diskNew; break; } } // Assume disk name is same as new pv var pvNewName = diskNewName; var newDiskID = await azureDiskClient.GetDiskResourceID(diskNewName); STEP("Unattach the disk"); await tkc.ReplacePvReclaimPolicy(pvNewName, "Retain"); await tkc.DeletePod(pod.Metadata.Name); await tkc.DeletePvc(pvcName); STEP("Building and attach the disk to a new pod"); var pod2 = new V1Pod { Metadata = new V1ObjectMeta { Name = "claim2", }, Spec = new V1PodSpec { RestartPolicy = "Never", Containers = new List <V1Container> { new V1Container { Image = "busybox", Args = new List <string> { "ls", "./af-vol" }, Name = "test", VolumeMounts = new List <V1VolumeMount> { new V1VolumeMount { MountPath = "/af-vol", Name = "af-pvc", } } } }, Volumes = new List <V1Volume> { new V1Volume { Name = "af-pvc", AzureDisk = new V1AzureDiskVolumeSource { Kind = "Managed", DiskName = diskNewName, DiskURI = newDiskID, } } } } }; await tkc.CreatePod(pod2); Assert.True(await tkc.WaitPodCompleted(pod2.Metadata.Name), "New pod construction failed"); STEP("Validate disk data remain"); var log = await tkc.ReadPodLog(pod2.Metadata.Name); Assert.True(log.Contains("temp"), "Cannot find the target file in the mount path"); STEP("Validate dynamic delete the disk with reclaim \"delete\""); await tkc.ReplacePvReclaimPolicy(pvNewName, "Delete"); await tkc.DeletePod(pod2.Metadata.Name); Assert.True(await azureDiskClient.ValidateDiskDeleted(diskNewName), "Fail to dynamic delete the azure disk"); }
public void FieldComparisonTests() { var x = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = "device1", [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname" }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", StorageClassName = "angela", AccessModes = new List <string> { "ReadOnce" }, Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; var y = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta( name: "pvc1", labels: new Dictionary <string, string> { [KubernetesConstants.K8sEdgeDeviceLabel] = "device1", [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname" }), Spec = new V1PersistentVolumeClaimSpec { VolumeName = "steve", StorageClassName = "angela", AccessModes = new List <string> { "ReadOnce" }, Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") } } } }; x.Metadata.Name = "pvc2"; Assert.False(comparer.Equals(x, y)); x.Metadata.Name = "pvc1"; Assert.True(comparer.Equals(x, y)); x.Metadata.Labels[KubernetesConstants.K8sEdgeDeviceLabel] = "device2"; Assert.False(comparer.Equals(x, y)); x.Metadata.Labels[KubernetesConstants.K8sEdgeDeviceLabel] = "device1"; Assert.True(comparer.Equals(x, y)); // Match Either VolumeName or StorageClassName x.Spec.VolumeName = "artemus"; Assert.True(comparer.Equals(x, y)); x.Spec.VolumeName = "steve"; x.Spec.StorageClassName = "dakota"; Assert.True(comparer.Equals(x, y)); // Both VolumeName and StorageClassName differ x.Spec.VolumeName = "artemus"; x.Spec.StorageClassName = "dakota"; Assert.False(comparer.Equals(x, y)); x.Spec.VolumeName = "steve"; x.Spec.StorageClassName = "angela"; Assert.True(comparer.Equals(x, y)); x.Spec.Resources.Requests = null; Assert.False(comparer.Equals(x, y)); x.Spec.Resources.Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("10M") }; Assert.True(comparer.Equals(x, y)); x.Spec.AccessModes = new List <string> { "ReadOnlyMany" }; Assert.False(comparer.Equals(x, y)); x.Spec.AccessModes = new List <string> { "ReadOnce" }; Assert.True(comparer.Equals(x, y)); }
internal void AddServicePod(string podName) { podName = podName.ToLower(); var appLabel = new Dictionary <string, string> { { "app", podName } }; using (Stream stream = KubeConfigStream) { var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(stream); using (IKubernetes client = new Kubernetes(config)) { var deployment = new Appsv1beta1Deployment("apps/v1beta1", "Deployment") { Metadata = new V1ObjectMeta() { Name = podName }, Spec = new Appsv1beta1DeploymentSpec() { Template = new V1PodTemplateSpec() { Metadata = new V1ObjectMeta() { Labels = appLabel }, Spec = new V1PodSpec() { Containers = new k8s.Models.V1Container[] { new V1Container { Name = podName, Image = "openhackteam5.azurecr.io/minecraft-server:2.0", VolumeMounts = new V1VolumeMount[] { new k8s.Models.V1VolumeMount { Name = "volume", MountPath = "/data" } }, Ports = new V1ContainerPort[] { new V1ContainerPort(25565, name: "port25565"), new V1ContainerPort(25575, name: "port25575") }, Env = new V1EnvVar[] { new V1EnvVar("EULA", true.ToString()) } } }, Volumes = new V1Volume[] { new V1Volume("volume", persistentVolumeClaim: new V1PersistentVolumeClaimVolumeSource(podName + SuffixPVC)) }, ImagePullSecrets = new V1LocalObjectReference[] { new V1LocalObjectReference("acr-auth") } } } } }; var loadBalancer = new V1Service("v1", "Service") { Metadata = new V1ObjectMeta { Name = podName + SuffixLoadBalancer }, Spec = new V1ServiceSpec { Type = "LoadBalancer", Ports = new V1ServicePort[] { new V1ServicePort(25565, "port25565", targetPort: 25565), new V1ServicePort(25575, "port25575", targetPort: 25575) }, Selector = appLabel } }; var persistentVolumeClaim = new V1PersistentVolumeClaim() { Metadata = new V1ObjectMeta() { Name = podName + SuffixPVC, NamespaceProperty = DefaultNamespace }, Spec = new V1PersistentVolumeClaimSpec { AccessModes = new string[] { "ReadWriteMany" }, StorageClassName = "azurefile", Resources = new V1ResourceRequirements(requests: new Dictionary <string, ResourceQuantity> { { "storage", new ResourceQuantity("5Gi") } }) }, Status = new V1PersistentVolumeClaimStatus() }; var pvcs = client.ListDeploymentForAllNamespaces1(); client.CreateNamespacedPersistentVolumeClaim(persistentVolumeClaim, DefaultNamespace); client.CreateNamespacedDeployment1(deployment, DefaultNamespace); client.CreateNamespacedService(loadBalancer, DefaultNamespace); } } }
private async Task <string> DescribeObject(Kubernetes client, V1Namespace ns, V1PersistentVolumeClaim o, StringBuilder buffer) { var fetched = await client.ReadNamespacedPersistentVolumeClaimAsync(o.Metadata.Name, ns.Metadata.Name).ConfigureAwait(false); buffer.AppendLine($"API Veresion: {fetched.ApiVersion}"); buffer.AppendLine($"Kind: {fetched.Kind}"); buffer.AppendLine(DescribeMetadata(fetched.Metadata)); return($"Persistent Volume Claim - {fetched.Metadata.Name}"); }
public async Task CreatePvc(V1PersistentVolumeClaim pvc) { logger.LogInformation("Creating pvc {0} in namespace {1}", pvc.Metadata.Name, ns); await client.CreateNamespacedPersistentVolumeClaimAsync(pvc, ns); }
private async Task Update() { Item = await State.Client.ReadNamespacedPersistentVolumeClaimAsync(Name, Namespace); StateHasChanged(); }
private async Task Delete(V1PersistentVolumeClaim item) { await State.Client.DeleteNamespacedPersistentVolumeClaimAsync(item.Metadata.Name, item.Metadata.NamespaceProperty); }
public Server Create(string name) { var result = new Server(); if (Found(name)) { throw new Exception("name already exits"); } var labels = new Dictionary <string, string>() { { "app", name }, { "type", "raincraft" } }; var claim = new V1PersistentVolumeClaim() { ApiVersion = "v1", Kind = "PersistentVolumeClaim", Metadata = new V1ObjectMeta() { Name = name }, Spec = new V1PersistentVolumeClaimSpec() { AccessModes = new[] { "ReadWriteMany" }, StorageClassName = "minesc2", Resources = new V1ResourceRequirements() { Requests = new Dictionary <string, ResourceQuantity>() { { "storage", new ResourceQuantity("5Gi") } } } } }; Cluster.CreateNamespacedPersistentVolumeClaim(claim, "default"); var deployment = new V1Deployment() { ApiVersion = "apps/v1", Kind = "Deployment", Metadata = new V1ObjectMeta() { Name = name, }, Spec = new V1DeploymentSpec() { Replicas = 1, Template = new V1PodTemplateSpec() { Metadata = new V1ObjectMeta() { Name = name, Labels = labels }, Spec = new V1PodSpec() { Containers = new List <V1Container>(new[] { new V1Container() { Name = name, Image = "openhack/minecraft-server:2.0-alpine", Ports = new List <V1ContainerPort>(new[] { new V1ContainerPort() { ContainerPort = 25565 }, new V1ContainerPort() { ContainerPort = 25575 }, }), Env = new List <V1EnvVar>(new[] { new V1EnvVar() { Name = "EULA", Value = "true" } }), VolumeMounts = new List <V1VolumeMount>(new[] { new V1VolumeMount() { Name = "minedb", MountPath = "/data" } }) } }), Volumes = new List <V1Volume>(new[] { new V1Volume() { Name = "minedb", PersistentVolumeClaim = new V1PersistentVolumeClaimVolumeSource() { ClaimName = name } } }) } }, Selector = new V1LabelSelector() { MatchLabels = labels } } }; deployment = Cluster.CreateNamespacedDeployment(deployment, "default"); var service = Cluster.CreateNamespacedService(new V1Service() { ApiVersion = "v1", Kind = "Service", Metadata = new V1ObjectMeta() { Name = name, Labels = labels }, Spec = new V1ServiceSpec() { Type = "LoadBalancer", Ports = new List <V1ServicePort>(new[] { new V1ServicePort() { Name = "25565", Protocol = "TCP", Port = 25565, TargetPort = new IntstrIntOrString("25565") }, new V1ServicePort() { Name = "25575", Protocol = "TCP", Port = 25575, TargetPort = new IntstrIntOrString("25575") } }), Selector = labels } }, "default"); result.Name = service.Metadata.Name; foreach (var i in service.Status.LoadBalancer.Ingress) { result.Endpoints.Add(new ServerEndpoint() { Minecraft = i.Ip, Rcon = "25565" }); result.Endpoints.Add(new ServerEndpoint() { Minecraft = i.Ip, Rcon = "25575" }); } return(result); }
public async Task PodWithPvc() { var testNamespace = Guid.NewGuid().ToString();; var tkc = new TestKubernetesClient(testNamespace, loggerFactory.CreateLogger <TestKubernetesClient>()); var pvcName = "pvc1"; var pvc = new V1PersistentVolumeClaim { Metadata = new V1ObjectMeta { Name = pvcName, }, Spec = new V1PersistentVolumeClaimSpec { AccessModes = new List <string> { "ReadWriteOnce" }, StorageClassName = "azurefile-csi", Resources = new V1ResourceRequirements { Requests = new Dictionary <string, ResourceQuantity> { ["storage"] = new ResourceQuantity("2Gi"), }, }, }, }; var pod = new V1Pod { Metadata = new V1ObjectMeta { Name = "claim", }, Spec = new V1PodSpec { RestartPolicy = "Never", Containers = new List <V1Container> { new V1Container { Image = "busybox", Args = new List <string> { "ls", "/" }, Name = "test", VolumeMounts = new List <V1VolumeMount> { new V1VolumeMount { MountPath = "/af-vol", Name = "af-pvc", } } } }, Volumes = new List <V1Volume> { new V1Volume { Name = "af-pvc", PersistentVolumeClaim = new V1PersistentVolumeClaimVolumeSource { ClaimName = pvcName }, } } } }; await tkc.EnsureNamespace(); await tkc.CreatePvc(pvc); await tkc.CreatePod(pod); // TODO verify pod status, share content, and do clean up }
public void UpdatePersistentVolumeClaim(V1PersistentVolumeClaim to, V1PersistentVolumeClaim from) { to.Metadata.ResourceVersion = from.Metadata.ResourceVersion; }
public async Task CreatePvc(V1PersistentVolumeClaim pvc) { await client.CreateNamespacedPersistentVolumeClaimAsync(pvc, ns); }