Skip to content

Commit

Permalink
Add API for status and scale subresources
Browse files Browse the repository at this point in the history
  • Loading branch information
iabudiab committed Sep 3, 2021
1 parent 5e3b1ee commit d8bb8a5
Show file tree
Hide file tree
Showing 6 changed files with 568 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,57 @@ public extension ClusterScopedGenericKubernetesClient where Resource: Collection
super.deleteAll(in: .allNamespaces)
}
}

// MARK: - StatusHavingResource

/// API functions for `StatusHavingResource`.
public extension ClusterScopedGenericKubernetesClient where Resource: StatusHavingResource {

/// Loads an API resource's status by name.
///
/// - Parameters:
/// - name: The name of the API resource to load.
///
/// - Returns: An `EventLoopFuture` holding the API resource specified by the given name.
func getStatus(name: String) throws -> EventLoopFuture<Resource> {
try super.getStatus(in: .allNamespaces, name: name)
}

/// Replaces, i.e. updates, an API resource's status .
///
/// - Parameters:
/// - name: The name of the resoruce to update.
/// - resource: A `KubernetesAPIResource` instance to update.
///
/// - Returns: An `EventLoopFuture` holding the updated `KubernetesAPIResource`.
func updateStatus(name: String, _ resource: Resource) throws -> EventLoopFuture<Resource> {
try super.updateStatus(in: .allNamespaces, name: name, resource)
}
}

// MARK: - ScalableResource

/// API functions for `ScalableResource`.
public extension ClusterScopedGenericKubernetesClient where Resource: ScalableResource {

/// Loads an API resource's scale by name.
///
/// - Parameters:
/// - name: The name of the API resource to load.
///
/// - Returns: An `EventLoopFuture` holding the `autoscaling.v1.Scale` of the resource specified by the given name.
func getScale(name: String) throws -> EventLoopFuture<autoscaling.v1.Scale> {
try super.getScale(in: .allNamespaces, name: name)
}

/// Replaces, i.e. updates, an API resource's scale.
///
/// - Parameters:
/// - name: The name of the resoruce to update.
/// - resource: A `autoscaling.v1.Scale` instance to update.
///
/// - Returns: An `EventLoopFuture` holding the updated `autoscaling.v1.Scale`.
func updateScale(name: String, scale: autoscaling.v1.Scale) throws -> EventLoopFuture<autoscaling.v1.Scale> {
try super.updateScale(in: .allNamespaces, name: name, scale: scale)
}
}
123 changes: 89 additions & 34 deletions Sources/SwiftkubeClient/Client/GenericKubernetesClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public class GenericKubernetesClient<Resource: KubernetesAPIResource> {
public func get(in namespace: NamespaceSelector, name: String, options: [ReadOption]? = nil) -> EventLoopFuture<Resource> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.GET).resource(withName: name).in(namespace).with(options: options).build()
let request = try makeRequest().in(namespace).toGet().resource(withName: name).with(options: options).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
Expand All @@ -106,7 +106,7 @@ public class GenericKubernetesClient<Resource: KubernetesAPIResource> {
public func create(in namespace: NamespaceSelector, _ resource: Resource) -> EventLoopFuture<Resource> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.POST).resource(resource).in(namespace).build()
let request = try makeRequest().in(namespace).toPost().body(resource).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
Expand All @@ -126,7 +126,7 @@ public class GenericKubernetesClient<Resource: KubernetesAPIResource> {
public func update(in namespace: NamespaceSelector, _ resource: Resource) -> EventLoopFuture<Resource> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.PUT).resource(withName: resource.name).resource(resource).in(namespace).build()
let request = try makeRequest().in(namespace).toPut().resource(withName: resource.name).body(.resource(payload: resource)).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
Expand All @@ -146,7 +146,7 @@ public class GenericKubernetesClient<Resource: KubernetesAPIResource> {
public func delete(in namespace: NamespaceSelector, name: String, options: meta.v1.DeleteOptions?) -> EventLoopFuture<ResourceOrStatus<Resource>> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.DELETE).resource(withName: name).in(namespace).build()
let request = try makeRequest().in(namespace).toDelete().resource(withName: name).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
Expand All @@ -164,7 +164,7 @@ public class GenericKubernetesClient<Resource: KubernetesAPIResource> {
public func deleteAll(in namespace: NamespaceSelector) -> EventLoopFuture<ResourceOrStatus<Resource>> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.DELETE).in(namespace).build()
let request = try makeRequest().in(namespace).toDelete().build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
Expand All @@ -187,7 +187,87 @@ public extension GenericKubernetesClient where Resource: ListableResource {
func list(in namespace: NamespaceSelector, options: [ListOption]? = nil) -> EventLoopFuture<Resource.List> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.GET).in(namespace).with(options: options).build()
let request = try makeRequest().in(namespace).toGet().with(options: options).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
return httpClient.eventLoopGroup.next().makeFailedFuture(error)
}
}
}

internal extension GenericKubernetesClient where Resource: ScalableResource {

/// Reads a resource's scale in the given namespace.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the resource to load.
///
/// - Returns: An `EventLoopFuture` holding the `autoscaling.v1.Scale` for the desired resource .
func getScale(in namespace: NamespaceSelector, name: String) throws -> EventLoopFuture<autoscaling.v1.Scale> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().in(namespace).toGet().resource(withName: name).subResource(.scale).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
return httpClient.eventLoopGroup.next().makeFailedFuture(error)
}
}

/// Replaces the resource's scale in the given namespace.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the resource to update.
/// - scale: An instance of `autoscaling.v1.Scale` to replace.
///
/// - Returns: An `EventLoopFuture` holding the updated `autoscaling.v1.Scale` for the desired resource .
func updateScale(in namespace: NamespaceSelector, name: String, scale: autoscaling.v1.Scale) throws -> EventLoopFuture<autoscaling.v1.Scale> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().in(namespace).toPut().resource(withName: name).body(.subResource(type: .scale, payload: scale)).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
return httpClient.eventLoopGroup.next().makeFailedFuture(error)
}
}
}

internal extension GenericKubernetesClient where Resource: StatusHavingResource {

/// Reads a resource's status in the given namespace.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the resource to load.
///
/// - Returns: An `EventLoopFuture` holding the `KubernetesAPIResource`.
func getStatus(in namespace: NamespaceSelector, name: String) throws -> EventLoopFuture<Resource> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().in(namespace).toGet().resource(withName: name).subResource(.status).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
return httpClient.eventLoopGroup.next().makeFailedFuture(error)
}
}

/// Replaces the resource's status in the given namespace.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the resource to update.
/// - resource: A `KubernetesAPIResource` instance to update.
///
/// - Returns: An `EventLoopFuture` holding the updated `KubernetesAPIResource`.
func updateStatus(in namespace: NamespaceSelector, name: String, _ resource: Resource) throws -> EventLoopFuture<Resource> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().in(namespace).toPut().resource(withName: name).body(.subResource(type: .status, payload: resource)).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
Expand All @@ -198,7 +278,7 @@ public extension GenericKubernetesClient where Resource: ListableResource {

internal extension GenericKubernetesClient {

func makeRequest() -> RequestBuilder<Resource> {
func makeRequest() -> NamespaceStep {
RequestBuilder(config: config, gvk: gvk)
}

Expand Down Expand Up @@ -263,31 +343,6 @@ internal extension GenericKubernetesClient {
}
}

internal extension GenericKubernetesClient {

func status(in namespace: NamespaceSelector, name: String) throws -> EventLoopFuture<Resource> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.GET).resource(withName: name).status().in(namespace).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
return httpClient.eventLoopGroup.next().makeFailedFuture(error)
}
}

func updateStatus(in namespace: NamespaceSelector, _ resource: Resource) throws -> EventLoopFuture<Resource> {
do {
let eventLoop = httpClient.eventLoopGroup.next()
let request = try makeRequest().to(.PUT).resource(resource).status().in(namespace).build()

return dispatch(request: request, eventLoop: eventLoop)
} catch {
return httpClient.eventLoopGroup.next().makeFailedFuture(error)
}
}
}

internal extension GenericKubernetesClient {

/// Watches the API resources in the given namespace.
Expand Down Expand Up @@ -330,7 +385,7 @@ internal extension GenericKubernetesClient {
retryStrategy: RetryStrategy = RetryStrategy(),
using delegate: Delegate
) throws -> SwiftkubeClientTask {
let request = try makeRequest().toWatch().in(namespace).with(options: options).build()
let request = try makeRequest().in(namespace).toWatch().with(options: options).build()
let watcher = ResourceWatcher(decoder: jsonDecoder, delegate: delegate)
let clientDelegate = ClientStreamingDelegate(watcher: watcher, logger: logger)

Expand Down Expand Up @@ -384,7 +439,7 @@ internal extension GenericKubernetesClient {
retryStrategy: RetryStrategy = RetryStrategy.never,
delegate: LogWatcherDelegate
) throws -> SwiftkubeClientTask {
let request = try makeRequest().toFollow(pod: name, container: container).in(namespace).build()
let request = try makeRequest().in(namespace).toFollow(pod: name, container: container).build()
let watcher = LogWatcher(delegate: delegate)
let clientDelegate = ClientStreamingDelegate(watcher: watcher, logger: logger)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,4 @@ public extension NamespacedGenericKubernetesClient where Resource == core.v1.Pod
delegate: delegate
)
}

func status(in namespace: NamespaceSelector? = nil, name: String) throws -> EventLoopFuture<core.v1.Pod> {
try super.status(in: namespace ?? .namespace(config.namespace), name: name)
}

func updateStatus(in namespace: NamespaceSelector? = nil, _ pod: core.v1.Pod) throws -> EventLoopFuture<core.v1.Pod> {
try super.updateStatus(in: namespace ?? .namespace(config.namespace), pod)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public extension NamespacedGenericKubernetesClient where Resource: ReplaceableRe
/// - namespace: The namespace for this API request.
/// - resource: A `KubernetesAPIResource` instance to update.
///
/// - Returns: An `EventLoopFuture` holding the created `KubernetesAPIResource`.
/// - Returns: An `EventLoopFuture` holding the updated `KubernetesAPIResource`.
func update(inNamespace namespace: NamespaceSelector? = nil, _ resource: Resource) -> EventLoopFuture<Resource> {
super.update(in: namespace ?? .namespace(config.namespace), resource)
}
Expand Down Expand Up @@ -233,3 +233,69 @@ public extension NamespacedGenericKubernetesClient where Resource: CollectionDel
super.deleteAll(in: namespace ?? .namespace(config.namespace))
}
}

// MARK: - StatusHavingResource

/// API functions for `StatusHavingResource`.
public extension NamespacedGenericKubernetesClient where Resource: StatusHavingResource {

/// Loads an API resource's status by name in the given namespace.
///
/// If the namespace is not specified then the default namespace defined in the `KubernetesClientConfig` will be used instead.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the API resource to load.
///
/// - Returns: An `EventLoopFuture` holding the API resource specified by the given name in the given namespace.
func getStatus(in namespace: NamespaceSelector? = nil, name: String) throws -> EventLoopFuture<Resource> {
try super.getStatus(in: namespace ?? .namespace(config.namespace), name: name)
}

/// Replaces, i.e. updates, an API resource's status in the given namespace.
///
/// If the namespace is not specified then the default namespace defined in the `KubernetesClientConfig` will be used instead.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the resoruce to update.
/// - resource: A `KubernetesAPIResource` instance to update.
///
/// - Returns: An `EventLoopFuture` holding the updated `KubernetesAPIResource`.
func updateStatus(in namespace: NamespaceSelector? = nil, name: String, _ resource: Resource) throws -> EventLoopFuture<Resource> {
try super.updateStatus(in: namespace ?? .namespace(config.namespace), name: name, resource)
}
}

// MARK: - ScalableResource

/// API functions for `ScalableResource`.
public extension NamespacedGenericKubernetesClient where Resource: ScalableResource {

/// Loads an API resource's scale by name in the given namespace.
///
/// If the namespace is not specified then the default namespace defined in the `KubernetesClientConfig` will be used instead.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the API resource to load.
///
/// - Returns: An `EventLoopFuture` holding the `autoscaling.v1.Scale` of the resource specified by the given name in the given namespace.
func getScale(in namespace: NamespaceSelector? = nil, name: String) throws -> EventLoopFuture<autoscaling.v1.Scale> {
try super.getScale(in: namespace ?? .namespace(config.namespace), name: name)
}

/// Replaces, i.e. updates, an API resource's scale in the given namespace.
///
/// If the namespace is not specified then the default namespace defined in the `KubernetesClientConfig` will be used instead.
///
/// - Parameters:
/// - namespace: The namespace for this API request.
/// - name: The name of the resoruce to update.
/// - resource: A `autoscaling.v1.Scale` instance to update.
///
/// - Returns: An `EventLoopFuture` holding the updated `autoscaling.v1.Scale`.
func updateScale(in namespace: NamespaceSelector? = nil, name: String, scale: autoscaling.v1.Scale) throws -> EventLoopFuture<autoscaling.v1.Scale> {
try super.updateScale(in: namespace ?? .namespace(config.namespace), name: name, scale: scale)
}
}
Loading

0 comments on commit d8bb8a5

Please sign in to comment.