From 93c49f06ca32dbdbb01b152b6cd18d077da402e7 Mon Sep 17 00:00:00 2001 From: Elias Wilken Date: Wed, 23 Aug 2023 18:14:22 +0200 Subject: [PATCH 1/3] add `previous` & `timestamps` flags to log requests --- .../Client/GenericKubernetesClient.swift | 7 ++++--- ...amespacedGenericKubernetesClient+Pod.swift | 10 +++++++-- .../Client/RequestBuilder.swift | 21 +++++++++++++++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift b/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift index 15dfd6e..8ca4ebe 100644 --- a/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift +++ b/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift @@ -259,10 +259,10 @@ internal extension GenericKubernetesClient { /// /// - Returns: The container logs as a single String. /// - Throws: An error of type ``SwiftkubeClientError``. - func logs(in namespace: NamespaceSelector, name: String, container: String?) async throws -> String { + func logs(in namespace: NamespaceSelector, name: String, container: String?, previous: Bool = false, timestamps: Bool = false) async throws -> String { let request = try makeRequest() .in(namespace) - .toLogs(pod: name, container: container) + .toLogs(pod: name, container: container, previous: previous, timestamps: timestamps) .subResource(.log) .build() @@ -427,9 +427,10 @@ public extension GenericKubernetesClient { in namespace: NamespaceSelector, name: String, container: String?, + timestamps: Bool = false, retryStrategy: RetryStrategy = RetryStrategy.never ) throws -> SwiftkubeClientTask { - let request = try makeRequest().in(namespace).toFollow(pod: name, container: container).build() + let request = try makeRequest().in(namespace).toFollow(pod: name, container: container, timestamps: timestamps).build() return SwiftkubeClientTask( client: httpClient, diff --git a/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift b/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift index e3b008d..33d7e39 100644 --- a/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift +++ b/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift @@ -70,12 +70,14 @@ public extension NamespacedGenericKubernetesClient where Resource == core.v1.Pod in namespace: NamespaceSelector? = nil, name: String, container: String? = nil, + timestamps: Bool = false, retryStrategy: RetryStrategy = RetryStrategy.never ) throws -> SwiftkubeClientTask { try super.follow( in: namespace ?? .namespace(config.namespace), name: name, container: container, + timestamps: timestamps, retryStrategy: retryStrategy ) } @@ -94,12 +96,16 @@ public extension NamespacedGenericKubernetesClient where Resource == core.v1.Pod func logs( in namespace: NamespaceSelector? = nil, name: String, - container: String? = nil + container: String? = nil, + previous: Bool = false, + timestamps: Bool = false ) async throws -> String { try await super.logs( in: namespace ?? .namespace(config.namespace), name: name, - container: container + container: container, + previous: previous, + timestamps: timestamps ) } } diff --git a/Sources/SwiftkubeClient/Client/RequestBuilder.swift b/Sources/SwiftkubeClient/Client/RequestBuilder.swift index f11a253..da5c643 100644 --- a/Sources/SwiftkubeClient/Client/RequestBuilder.swift +++ b/Sources/SwiftkubeClient/Client/RequestBuilder.swift @@ -50,11 +50,11 @@ internal protocol NamespaceStep { internal protocol MethodStep { func toGet() -> GetStep func toWatch() -> GetStep - func toFollow(pod: String, container: String?) -> GetStep + func toFollow(pod: String, container: String?, timestamps: Bool) -> GetStep func toPost() -> PostStep func toPut() -> PutStep func toDelete() -> DeleteStep - func toLogs(pod: String, container: String?) -> GetStep + func toLogs(pod: String, container: String?, previous: Bool, timestamps: Bool) -> GetStep } // MARK: - GetStep @@ -131,6 +131,8 @@ internal class RequestBuilder { var deleteOptions: meta.v1.DeleteOptions? var watchFlag = false var followFlag = false + var previousFlag = false + var timestampsFlag = false init(config: KubernetesClientConfig, gvr: GroupVersionResource) { self.config = config @@ -194,20 +196,23 @@ extension RequestBuilder: MethodStep { /// Set request method to GET and notice the pod and container to follow for the pending request /// - Returns:The builder instance as GetStep - func toFollow(pod: String, container: String?) -> GetStep { + func toFollow(pod: String, container: String?, timestamps: Bool = false) -> GetStep { method = .GET resourceName = pod containerName = container subResourceType = .log followFlag = true + timestampsFlag = timestamps return self as GetStep } - func toLogs(pod: String, container: String?) -> GetStep { + func toLogs(pod: String, container: String?, previous: Bool = false, timestamps: Bool = false) -> GetStep { method = .GET resourceName = pod containerName = container subResourceType = .log + previousFlag = previous + timestampsFlag = timestamps return self as GetStep } } @@ -343,6 +348,14 @@ internal extension RequestBuilder { add(queryItem: URLQueryItem(name: "follow", value: "true")) } + if previousFlag { + add(queryItem: URLQueryItem(name: "previous", value: "true")) + } + + if timestampsFlag { + add(queryItem: URLQueryItem(name: "timestamps", value: "true")) + } + if let container = containerName { add(queryItem: URLQueryItem(name: "container", value: container)) } From c5fccd995a0eddb32b73e2b17721dbf9edd45f49 Mon Sep 17 00:00:00 2001 From: Elias Wilken Date: Wed, 6 Sep 2023 09:24:53 +0200 Subject: [PATCH 2/3] add tests for `previous` & `timestamps` flags on log requests --- .../RequestBuilderTests.swift | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/Tests/SwiftkubeClientTests/RequestBuilderTests.swift b/Tests/SwiftkubeClientTests/RequestBuilderTests.swift index 3ee2d6f..c5c3398 100644 --- a/Tests/SwiftkubeClientTests/RequestBuilderTests.swift +++ b/Tests/SwiftkubeClientTests/RequestBuilderTests.swift @@ -76,15 +76,23 @@ final class RequestBuilderTests: XCTestCase { func testFollowInNamespace() { let builder = RequestBuilder(config: config, gvr: gvr) - let request = try? builder.in(.system).toFollow(pod: "pod", container: "container").build() + let request = try? builder.in(.system).toFollow(pod: "pod", container: "container", timestamps: false).build() XCTAssertEqual(request?.url, URL(string: "https://kubernetesmaster/api/v1/namespaces/kube-system/pods/pod/log?follow=true&container=container")!) XCTAssertEqual(request?.method, HTTPMethod.GET) } + + func testFollowWithTimestampsInNamespace() { + let builder = RequestBuilder(config: config, gvr: gvr) + let request = try? builder.in(.system).toFollow(pod: "pod", container: "container", timestamps: true).build() + + XCTAssertEqual(request?.url, URL(string: "https://kubernetesmaster/api/v1/namespaces/kube-system/pods/pod/log?follow=true×tamps=true&container=container")!) + XCTAssertEqual(request?.method, HTTPMethod.GET) + } func testLogsInNamespace() { let builder = RequestBuilder(config: config, gvr: gvr) - let request = try? builder.in(.system).toLogs(pod: "pod", container: nil).build() + let request = try? builder.in(.system).toLogs(pod: "pod", container: nil, previous: false, timestamps: false).build() XCTAssertEqual(request?.url, URL(string: "https://kubernetesmaster/api/v1/namespaces/kube-system/pods/pod/log")!) XCTAssertEqual(request?.method, HTTPMethod.GET) @@ -92,12 +100,28 @@ final class RequestBuilderTests: XCTestCase { func testLogsWithContainerInNamespace() { let builder = RequestBuilder(config: config, gvr: gvr) - let request = try? builder.in(.system).toLogs(pod: "pod", container: "container").build() + let request = try? builder.in(.system).toLogs(pod: "pod", container: "container", previous: false, timestamps: false).build() XCTAssertEqual(request?.url, URL(string: "https://kubernetesmaster/api/v1/namespaces/kube-system/pods/pod/log?container=container")!) XCTAssertEqual(request?.method, HTTPMethod.GET) } + func testLogsWithPreviousInNamespace() { + let builder = RequestBuilder(config: config, gvr: gvr) + let request = try? builder.in(.system).toLogs(pod: "pod", container: nil, previous: true, timestamps: false).build() + + XCTAssertEqual(request?.url, URL(string: "https://kubernetesmaster/api/v1/namespaces/kube-system/pods/pod/log?previous=true")!) + XCTAssertEqual(request?.method, HTTPMethod.GET) + } + + func testLogsWithTimestampsInNamespace() { + let builder = RequestBuilder(config: config, gvr: gvr) + let request = try? builder.in(.system).toLogs(pod: "pod", container: nil, previous: false, timestamps: true).build() + + XCTAssertEqual(request?.url, URL(string: "https://kubernetesmaster/api/v1/namespaces/kube-system/pods/pod/log?timestamps=true")!) + XCTAssertEqual(request?.method, HTTPMethod.GET) + } + func testGetWithListOptions_Eq() { let builder = RequestBuilder(config: config, gvr: gvr) let request = try? builder.in(.default).toGet().with(options: [ From f6d893cff0cc27f190aeb1e25644949c11458ac4 Mon Sep 17 00:00:00 2001 From: Elias Wilken Date: Sat, 9 Sep 2023 09:37:03 +0200 Subject: [PATCH 3/3] add forgotten doc comments --- Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift | 3 +++ .../Client/NamespacedGenericKubernetesClient+Pod.swift | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift b/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift index 8ca4ebe..20b77f4 100644 --- a/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift +++ b/Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift @@ -256,6 +256,8 @@ internal extension GenericKubernetesClient { /// - namespace: The namespace for this API request. /// - name: The name of the pod. /// - container: The name of the container. + /// - previous: Whether to request the logs of the previous instance of the container. + /// - timestamps: Whether to include timestamps on the log lines. /// /// - Returns: The container logs as a single String. /// - Throws: An error of type ``SwiftkubeClientError``. @@ -420,6 +422,7 @@ public extension GenericKubernetesClient { /// - namespace: The namespace for this API request. /// - name: The name of the Pod. /// - container: The name of the container. + /// - timestamps: Whether to include timestamps on the log lines. /// - retryStrategy: An instance of a ``RetryStrategy`` configuration to use. /// /// - Returns: A ``SwiftkubeClientTask`` instance, representing a streaming connection to the API server. diff --git a/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift b/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift index 33d7e39..847a922 100644 --- a/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift +++ b/Sources/SwiftkubeClient/Client/NamespacedGenericKubernetesClient+Pod.swift @@ -63,6 +63,7 @@ public extension NamespacedGenericKubernetesClient where Resource == core.v1.Pod /// - namespace: The namespace for this API request. /// - name: The name of the Pod. /// - container: The name of the container. + /// - timestamps: Whether to include timestamps on the log lines. /// - retryStrategy: An instance of a ``RetryStrategy`` configuration to use. /// /// - Returns: A ``SwiftkubeClientTask`` instance, representing a streaming connection to the API server. @@ -90,6 +91,8 @@ public extension NamespacedGenericKubernetesClient where Resource == core.v1.Pod /// - namespace: The namespace for this API request. /// - name: The name of the pod. /// - container: The name of the container. + /// - previous: Whether to request the logs of the previous instance of the container. + /// - timestamps: Whether to include timestamps on the log lines. /// /// - Returns: The container logs as a single String. /// - Throws: An error of type ``SwiftkubeClientError``.