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

Add optional previous & timestamps flags to log requests #35

Merged
merged 3 commits into from
Sep 11, 2023
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
10 changes: 7 additions & 3 deletions Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,15 @@ 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``.
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()

Expand Down Expand Up @@ -420,16 +422,18 @@ 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.
func follow(
in namespace: NamespaceSelector,
name: String,
container: String?,
timestamps: Bool = false,
retryStrategy: RetryStrategy = RetryStrategy.never
) throws -> SwiftkubeClientTask<String> {
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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,22 @@ 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.
func follow(
in namespace: NamespaceSelector? = nil,
name: String,
container: String? = nil,
timestamps: Bool = false,
retryStrategy: RetryStrategy = RetryStrategy.never
) throws -> SwiftkubeClientTask<String> {
try super.follow(
in: namespace ?? .namespace(config.namespace),
name: name,
container: container,
timestamps: timestamps,
retryStrategy: retryStrategy
)
}
Expand All @@ -88,18 +91,24 @@ 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``.
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
)
}
}
21 changes: 17 additions & 4 deletions Sources/SwiftkubeClient/Client/RequestBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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))
}
Expand Down
30 changes: 27 additions & 3 deletions Tests/SwiftkubeClientTests/RequestBuilderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,52 @@ 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&timestamps=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)
}

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: [
Expand Down