diff --git a/eng/Versions.props b/eng/Versions.props index e4ac997ca..a7a0c6159 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -27,7 +27,7 @@ 1.1.0 3.1.1 16.3.0 - 17.0.14 + 18.0.13 7.0.2 13.0.3 diff --git a/src/Kubernetes.Controller/Client/ResourceInformer.cs b/src/Kubernetes.Controller/Client/ResourceInformer.cs index d8b8c6124..b26287cf5 100644 --- a/src/Kubernetes.Controller/Client/ResourceInformer.cs +++ b/src/Kubernetes.Controller/Client/ResourceInformer.cs @@ -196,7 +196,8 @@ public override async Task RunAsync(CancellationToken cancellationToken) } } - protected abstract Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default); + protected abstract Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default); + protected abstract Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null); private static EventId EventId(EventType eventType) => new EventId((int)eventType, eventType.ToString()); @@ -254,14 +255,16 @@ private async Task ListAsync(CancellationToken cancellationToken) { // for anything which was previously known but not part of list // send a deleted notification to clear any observer caches - var item = new TResource() + var item = new TResource { ApiVersion = _names.GroupApiVersion, Kind = _names.Kind, - Metadata = new V1ObjectMeta( - name: key.Name, - namespaceProperty: key.Namespace, - ownerReferences: value), + Metadata = new V1ObjectMeta + { + Name = key.Name, + NamespaceProperty = key.Namespace, + OwnerReferences = value + } }; InvokeRegistrationCallbacks(WatchEventType.Deleted, item); @@ -291,15 +294,11 @@ private async Task WatchAsync(CancellationToken cancellationToken) var watcherCompletionSource = new TaskCompletionSource(); // begin watching where list left off - var watchWithHttpMessage = RetrieveResourceListAsync(watch: true, resourceVersion: _lastResourceVersion, resourceSelector: _selector, cancellationToken: cancellationToken); - - var lastEventUtc = DateTime.UtcNow; - using var watcher = watchWithHttpMessage.Watch( + var watcher = WatchResourceListAsync(resourceVersion: _lastResourceVersion, resourceSelector: _selector, (watchEventType, item) => { if (!watcherCompletionSource.Task.IsCompleted) { - lastEventUtc = DateTime.UtcNow; OnEvent(watchEventType, item); } }, @@ -325,7 +324,10 @@ private async Task WatchAsync(CancellationToken cancellationToken) () => { watcherCompletionSource.TrySetResult(0); - }); + } + ); + + var lastEventUtc = DateTime.UtcNow; // reconnect if no events have arrived after a certain time using var checkLastEventUtcTimer = new Timer( @@ -342,6 +344,7 @@ private async Task WatchAsync(CancellationToken cancellationToken) watcherCompletionSource.TrySetCanceled(); watcher.Dispose(); + } }, state: null, diff --git a/src/Kubernetes.Controller/Client/V1EndpointsResourceInformer.cs b/src/Kubernetes.Controller/Client/V1EndpointsResourceInformer.cs index 44f3a36f8..d4c524dd6 100644 --- a/src/Kubernetes.Controller/Client/V1EndpointsResourceInformer.cs +++ b/src/Kubernetes.Controller/Client/V1EndpointsResourceInformer.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using k8s; using k8s.Autorest; using k8s.Models; @@ -22,8 +23,13 @@ public V1EndpointsResourceInformer( { } - protected override Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) + protected override Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) { - return Client.CoreV1.ListEndpointsForAllNamespacesWithHttpMessagesAsync(watch: watch, resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + return Client.CoreV1.ListEndpointsForAllNamespacesWithHttpMessagesAsync(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + } + + protected override Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null) + { + return Client.CoreV1.WatchListEndpointsForAllNamespaces(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, onEvent: onEvent, onError: onError, onClosed: onClosed); } } diff --git a/src/Kubernetes.Controller/Client/V1IngressClassResourceInformer.cs b/src/Kubernetes.Controller/Client/V1IngressClassResourceInformer.cs index eb30ec526..0ecc4b28f 100644 --- a/src/Kubernetes.Controller/Client/V1IngressClassResourceInformer.cs +++ b/src/Kubernetes.Controller/Client/V1IngressClassResourceInformer.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using k8s; using k8s.Autorest; using k8s.Models; @@ -22,8 +23,13 @@ public V1IngressClassResourceInformer( { } - protected override Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) + protected override Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) { - return Client.NetworkingV1.ListIngressClassWithHttpMessagesAsync(watch: watch, resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + return Client.NetworkingV1.ListIngressClassWithHttpMessagesAsync(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + } + + protected override Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null) + { + return Client.NetworkingV1.WatchListIngressClass(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, onEvent: onEvent, onError: onError, onClosed: onClosed); } } diff --git a/src/Kubernetes.Controller/Client/V1IngressResourceInformer.cs b/src/Kubernetes.Controller/Client/V1IngressResourceInformer.cs index 15221cd78..b43c67615 100644 --- a/src/Kubernetes.Controller/Client/V1IngressResourceInformer.cs +++ b/src/Kubernetes.Controller/Client/V1IngressResourceInformer.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using k8s; using k8s.Autorest; using k8s.Models; @@ -22,8 +23,14 @@ public V1IngressResourceInformer( { } - protected override Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) + protected override Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) { - return Client.NetworkingV1.ListIngressForAllNamespacesWithHttpMessagesAsync(watch: watch, resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + return Client.NetworkingV1.ListIngressForAllNamespacesWithHttpMessagesAsync(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + } + + protected override Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null) + { + return Client.NetworkingV1.WatchListIngressForAllNamespaces(resourceVersion: resourceVersion, + fieldSelector: resourceSelector?.FieldSelector, onEvent: onEvent, onError: onError, onClosed: onClosed); } } diff --git a/src/Kubernetes.Controller/Client/V1IngressResourceStatusUpdater.cs b/src/Kubernetes.Controller/Client/V1IngressResourceStatusUpdater.cs index e14c27686..0c65b007d 100644 --- a/src/Kubernetes.Controller/Client/V1IngressResourceStatusUpdater.cs +++ b/src/Kubernetes.Controller/Client/V1IngressResourceStatusUpdater.cs @@ -37,12 +37,21 @@ public async Task UpdateStatusAsync(CancellationToken cancellationToken) var service = await _client.CoreV1.ReadNamespacedServiceStatusAsync(_options.ControllerServiceName, _options.ControllerServiceNamespace, cancellationToken: cancellationToken); if (service.Status?.LoadBalancer?.Ingress is { } loadBalancerIngresses) { - var status = new V1IngressStatus(new V1IngressLoadBalancerStatus(loadBalancerIngresses?.Select(ingress => new V1IngressLoadBalancerIngress + var status = new V1IngressStatus { - Hostname = ingress.Hostname, - Ip = ingress.Ip, - Ports = ingress.Ports?.Select(port => new V1IngressPortStatus(port.Port, port.Protocol, port.Error)).ToArray() - }).ToArray())); + LoadBalancer = new V1IngressLoadBalancerStatus + { + Ingress = loadBalancerIngresses?.Select(ingress => new V1IngressLoadBalancerIngress + { + Hostname = ingress.Hostname, + Ip = ingress.Ip, + Ports = ingress.Ports?.Select(port => new V1IngressPortStatus + { + Port = port.Port, Protocol = port.Protocol, Error = port.Error + }).ToArray() + }).ToArray() + } + }; var ingresses = _cache.GetIngresses().ToArray(); foreach (var ingress in ingresses) diff --git a/src/Kubernetes.Controller/Client/V1SecretResourceInformer.cs b/src/Kubernetes.Controller/Client/V1SecretResourceInformer.cs index 65995bd7c..de034001b 100644 --- a/src/Kubernetes.Controller/Client/V1SecretResourceInformer.cs +++ b/src/Kubernetes.Controller/Client/V1SecretResourceInformer.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using k8s; using k8s.Autorest; using k8s.Models; @@ -22,8 +23,13 @@ public V1SecretResourceInformer( { } - protected override Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) + protected override Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) { - return Client.CoreV1.ListSecretForAllNamespacesWithHttpMessagesAsync(watch: watch, resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + return Client.CoreV1.ListSecretForAllNamespacesWithHttpMessagesAsync(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + } + + protected override Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null) + { + return Client.CoreV1.WatchListSecretForAllNamespaces(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, onEvent: onEvent, onError: onError, onClosed: onClosed); } } diff --git a/src/Kubernetes.Controller/Client/V1ServiceResourceInformer.cs b/src/Kubernetes.Controller/Client/V1ServiceResourceInformer.cs index ea86e43b8..e19a517c4 100644 --- a/src/Kubernetes.Controller/Client/V1ServiceResourceInformer.cs +++ b/src/Kubernetes.Controller/Client/V1ServiceResourceInformer.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using k8s; using k8s.Autorest; using k8s.Models; @@ -22,8 +23,13 @@ public V1ServiceResourceInformer( { } - protected override Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) + protected override Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) { - return Client.CoreV1.ListServiceForAllNamespacesWithHttpMessagesAsync(watch: watch, resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + return Client.CoreV1.ListServiceForAllNamespacesWithHttpMessagesAsync(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + } + + protected override Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null) + { + return Client.CoreV1.WatchListServiceForAllNamespaces(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, onEvent: onEvent, onError: onError, onClosed: onClosed); } } diff --git a/test/Kubernetes.Tests/Client/V1DeploymentResourceInformer.cs b/test/Kubernetes.Tests/Client/V1DeploymentResourceInformer.cs index 4ae785a55..92144c2c0 100644 --- a/test/Kubernetes.Tests/Client/V1DeploymentResourceInformer.cs +++ b/test/Kubernetes.Tests/Client/V1DeploymentResourceInformer.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using k8s; using k8s.Autorest; using k8s.Models; @@ -22,8 +23,13 @@ public V1DeploymentResourceInformer( { } - protected override Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) + protected override Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) { - return Client.AppsV1.ListDeploymentForAllNamespacesWithHttpMessagesAsync(watch: watch, resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + return Client.AppsV1.ListDeploymentForAllNamespacesWithHttpMessagesAsync(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + } + + protected override Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null) + { + return Client.AppsV1.WatchListDeploymentForAllNamespaces(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, onEvent: onEvent, onError: onError, onClosed: onClosed); } } diff --git a/test/Kubernetes.Tests/Client/V1PodResourceInformer.cs b/test/Kubernetes.Tests/Client/V1PodResourceInformer.cs index 32ab54f28..df55b55bd 100644 --- a/test/Kubernetes.Tests/Client/V1PodResourceInformer.cs +++ b/test/Kubernetes.Tests/Client/V1PodResourceInformer.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using k8s; using k8s.Autorest; using k8s.Models; @@ -22,8 +23,13 @@ public V1PodResourceInformer( { } - protected override Task> RetrieveResourceListAsync(bool? watch = null, string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) + protected override Task> RetrieveResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, CancellationToken cancellationToken = default) { - return Client.CoreV1.ListPodForAllNamespacesWithHttpMessagesAsync(watch: watch, resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + return Client.CoreV1.ListPodForAllNamespacesWithHttpMessagesAsync(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, cancellationToken: cancellationToken); + } + + protected override Watcher WatchResourceListAsync(string resourceVersion = null, ResourceSelector resourceSelector = null, Action onEvent = null, Action onError = null, Action onClosed = null) + { + return Client.CoreV1.WatchListPodForAllNamespaces(resourceVersion: resourceVersion, fieldSelector: resourceSelector?.FieldSelector, onEvent: onEvent, onError: onError, onClosed: onClosed); } } diff --git a/test/Kubernetes.Tests/NamespacedNameTests.cs b/test/Kubernetes.Tests/NamespacedNameTests.cs index b415e6a43..ef83843cb 100644 --- a/test/Kubernetes.Tests/NamespacedNameTests.cs +++ b/test/Kubernetes.Tests/NamespacedNameTests.cs @@ -62,12 +62,12 @@ public void EqualityAndInequality( [Fact] public void NamespaceAndNameFromResource() { - var resource = new V1ConfigMap( - apiVersion: V1ConfigMap.KubeApiVersion, - kind: V1ConfigMap.KubeKind, - metadata: new V1ObjectMeta( - name: "the-name", - namespaceProperty: "the-namespace")); + var resource = new V1ConfigMap + { + ApiVersion = V1ConfigMap.KubeApiVersion, + Kind = V1ConfigMap.KubeKind, + Metadata = new V1ObjectMeta {Name = "the-name", NamespaceProperty = "the-namespace"} + }; var nn = NamespacedName.From(resource); @@ -78,11 +78,12 @@ public void NamespaceAndNameFromResource() [Fact] public void JustNameFromClusterResource() { - var resource = new V1ClusterRole( - apiVersion: V1ClusterRole.KubeApiVersion, - kind: V1ClusterRole.KubeKind, - metadata: new V1ObjectMeta( - name: "the-name")); + var resource = new V1ClusterRole + { + ApiVersion = V1ClusterRole.KubeApiVersion, + Kind = V1ClusterRole.KubeKind, + Metadata = new V1ObjectMeta { Name = "the-name" } + }; var nn = NamespacedName.From(resource); diff --git a/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiController.cs b/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiController.cs index a1c0f30e4..a771b5dfc 100644 --- a/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiController.cs +++ b/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiController.cs @@ -32,10 +32,10 @@ public async Task ListAsync(ListParameters parameters) var result = new KubernetesList( apiVersion: Version, kind: "PodList", - metadata: new V1ListMeta( - continueProperty: list.Continue, - remainingItemCount: null, - resourceVersion: list.ResourceVersion), + metadata: new V1ListMeta + { + ContinueProperty = list.Continue, RemainingItemCount = null, ResourceVersion = list.ResourceVersion + }, items: list.Items); return new ObjectResult(result); diff --git a/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiGroupController.cs b/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiGroupController.cs index d00529689..c120f101a 100644 --- a/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiGroupController.cs +++ b/test/Kubernetes.Tests/TestCluster/Controllers/ResourceApiGroupController.cs @@ -35,10 +35,10 @@ public async Task ListAsync(ListParameters parameters) var result = new KubernetesList( apiVersion: $"{Group}/{Version}", kind: "DeploymentList", - metadata: new V1ListMeta( - continueProperty: list.Continue, - remainingItemCount: null, - resourceVersion: list.ResourceVersion), + metadata: new V1ListMeta + { + ContinueProperty = list.Continue, RemainingItemCount = null, ResourceVersion = list.ResourceVersion + }, items: list.Items); return new ObjectResult(result);