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

Client builders accept backend options #121

Merged
merged 4 commits into from
May 19, 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
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ import dev.hnaderi.k8s.client.http4s.EmberKubernetesClient
import io.circe.Json
import org.http4s.circe._

val buildClient = EmberKubernetesClient.defaultConfig[IO, Json]
val buildClient = EmberKubernetesClient[IO].defaultConfig[Json]

val getNodes = buildClient.use(APIs.nodes.list().send)

Expand Down Expand Up @@ -221,10 +221,10 @@ val nodes = ZIOKubernetesClient.send(APIs.nodes.list())
```scala mdoc:compile-only
import dev.hnaderi.k8s.circe._
import dev.hnaderi.k8s.client.APIs
import dev.hnaderi.k8s.client.SttpKubernetesClient
import dev.hnaderi.k8s.client.SttpJdkURLClientBuilder
import sttp.client3.circe._

val client = SttpKubernetesClient.urlClient.defaultConfig[Json]
val client = SttpJdkURLClientBuilder.defaultConfig[Json]

val nodes = APIs.nodes.list().send(client)
nodes.body.items.flatMap(_.metadata).flatMap(_.name).foreach(println)
Expand Down
6 changes: 1 addition & 5 deletions examples/cross-platform/src/main/scala/EmberExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@
* limitations under the License.
*/

//> using dep "dev.hnaderi::scala-k8s-http4s-ember:0.11.1"
//> using dep "dev.hnaderi::scala-k8s-circe:0.11.1"
//> using dep "org.http4s::http4s-circe:0.23.19"

package example

import cats.effect._
Expand All @@ -33,7 +29,7 @@ import org.http4s.circe._

object EmberExample extends IOApp {

private val client = EmberKubernetesClient.defaultConfig[IO, Json]
private val client = EmberKubernetesClient[IO].defaultConfig[Json]

def operations(cl: HttpClient[IO]) = for {
_ <- APIs.namespace("default").configmaps.list.send(cl).flatMap(IO.println)
Expand Down
5 changes: 3 additions & 2 deletions examples/jvm/src/main/scala/Http4sExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import cats.implicits._
import dev.hnaderi.k8s.circe._
import dev.hnaderi.k8s.client._
import dev.hnaderi.k8s.client.http4s.EmberKubernetesClient
import dev.hnaderi.k8s.client.http4s.KClient
import dev.hnaderi.k8s.client.implicits._
import dev.hnaderi.k8s.implicits._
import fs2.Stream._
Expand All @@ -31,9 +32,9 @@ import org.http4s.circe._

object Http4sExample extends IOApp {

private val client = EmberKubernetesClient.defaultConfig[IO, Json]
private val client = EmberKubernetesClient[IO].defaultConfig[Json]

def watchNodes(cl: EmberKubernetesClient.KClient[IO]) =
def watchNodes(cl: KClient[IO]) =
CoreV1.nodes
.list()
.listen(cl)
Expand Down
9 changes: 2 additions & 7 deletions examples/jvm/src/main/scala/SttpMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,15 @@
* limitations under the License.
*/

//> using dep "dev.hnaderi::scala-k8s-sttp:0.11.1"
//> using dep "dev.hnaderi::scala-k8s-circe:0.11.1"
//> using dep "com.softwaremill.sttp.client3::circe:3.8.15"

package example

import dev.hnaderi.k8s.circe._
import dev.hnaderi.k8s.client.APIs
import dev.hnaderi.k8s.client.SttpKubernetesClient
import sttp.client3.circe._
import dev.hnaderi.k8s.client.SttpJdkURLClientBuilder

object SttpMain extends App {
val client = SttpKubernetesClient.urlClient.defaultConfig
// val client = SttpKubernetesClient.httpClientSync().defaultConfig
val client = SttpJdkURLClientBuilder.defaultConfig

val response = APIs.namespace("default").configmaps.list.send(client)
response.body.items.flatMap(_.metadata).flatMap(_.name).foreach(println)
Expand Down
22 changes: 17 additions & 5 deletions modules/http4s-blaze/src/main/scala/BlazeKubernetesClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,30 @@ package http4s

import cats.effect.kernel.Async
import cats.effect.kernel.Resource
import cats.effect.std.Env
import fs2.io.file.Files
import org.http4s.blaze.client.BlazeClientBuilder
import org.http4s.client.Client

import javax.net.ssl.SSLContext

object BlazeKubernetesClient extends Http4sKubernetesClient with JVMPlatform {
final class BlazeKubernetesClient[F[_]: Async: Files: Env] private (
builder: BlazeClientBuilder[F]
) extends JVMPlatform[F] {

override protected def buildClient[F[_]: Async]: Resource[F, Client[F]] =
BlazeClientBuilder[F].resource
override protected def buildClient: Resource[F, Client[F]] =
builder.resource

override protected def buildWithSSLContext[F[_]: Async]
override protected def buildWithSSLContext
: SSLContext => Resource[F, Client[F]] =
BlazeClientBuilder[F].withSslContext(_).resource
builder.withSslContext(_).resource

}

object BlazeKubernetesClient {
def apply[F[_]: Async: Files: Env]: BlazeKubernetesClient[F] =
new BlazeKubernetesClient(BlazeClientBuilder[F])
def apply[F[_]: Async: Files: Env](
builder: BlazeClientBuilder[F]
): BlazeKubernetesClient[F] = new BlazeKubernetesClient(builder)
}
51 changes: 25 additions & 26 deletions modules/http4s-ember/.js/src/main/scala/PlatformCompanion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
*/

package dev.hnaderi.k8s.client
package http4s

import cats.effect.kernel.Async
import cats.effect.kernel.Resource
import cats.effect.std.Env
import cats.syntax.all._
import dev.hnaderi.k8s.client.http4s.EmberKubernetesClient
import dev.hnaderi.k8s.utils._
import fs2.Chunk
import fs2.Stream
Expand All @@ -30,36 +31,38 @@ import fs2.io.net.tls.TLSContext
import org.http4s._
import scodec.bits.ByteVector

private[client] trait PlatformCompanion extends Http4sKubernetesClient {
self: EmberKubernetesClient =>
private[http4s] abstract class PlatformCompanion[F[_]: Async: Files: Env]
extends Http4sKubernetesClient[F] {
self: EmberKubernetesClient[F] =>

private def ssl[F[_]: Async: Files](
private def ssl(
caData: Option[String] = None,
caFile: Option[String],
clientCert: Option[String] = None,
clientCertFile: Option[String],
clientKey: Option[String] = None,
clientKeyFile: Option[String],
clientKeyPass: Option[String] = None
): Resource[F, TLSContext[F]] = Resource.eval(
for {
ca <- dataOrFile(caData, caFile)
cert <- dataOrFile(clientCert, clientCertFile)
key <- dataOrFile(clientKey, clientKeyFile)
} yield TLSContext.Builder
.forAsync[F]
.fromSecureContext(
SecureContext(
ca = ca.map(v => Seq(Left(v))),
cert = cert.map(v => Seq(Left(v))),
key = key.map(ck =>
Seq(SecureContext.Key(Left(ck), passphrase = clientKeyPass))
): Resource[F, TLSContext[F]] =
Resource.eval(
for {
ca <- dataOrFile(caData, caFile)
cert <- dataOrFile(clientCert, clientCertFile)
key <- dataOrFile(clientKey, clientKeyFile)
} yield TLSContext.Builder
.forAsync[F]
.fromSecureContext(
SecureContext(
ca = ca.map(v => Seq(Left(v))),
cert = cert.map(v => Seq(Left(v))),
key = key.map(ck =>
Seq(SecureContext.Key(Left(ck), passphrase = clientKeyPass))
)
)
)
)
)
)

private def dataOrFile[F[_]: Async: Files](
private def dataOrFile(
data: Option[String],
file: Option[String]
): F[Option[Chunk[Byte]]] = {
Expand All @@ -74,12 +77,10 @@ private[client] trait PlatformCompanion extends Http4sKubernetesClient {
.map(base64Data(_))
}

final override def fromConfig[F[_], T](
final override def fromConfig[T](
config: Config,
context: Option[String] = None
)(implicit
F: Async[F],
Files: Files[F],
enc: EntityEncoder[F, T],
dec: EntityDecoder[F, T],
builder: Builder[T],
Expand Down Expand Up @@ -114,16 +115,14 @@ private[client] trait PlatformCompanion extends Http4sKubernetesClient {

}

final override def from[F[_], T](
final override def from[T](
server: String,
ca: Option[Path] = None,
clientCert: Option[Path] = None,
clientKey: Option[Path] = None,
clientKeyPassword: Option[String] = None,
authentication: AuthenticationParams = AuthenticationParams.empty
)(implicit
F: Async[F],
Files: Files[F],
enc: EntityEncoder[F, T],
dec: EntityDecoder[F, T],
builder: Builder[T],
Expand Down
11 changes: 7 additions & 4 deletions modules/http4s-ember/.jvm/src/main/scala/PlatformCompanion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@
*/

package dev.hnaderi.k8s.client
package http4s

import cats.effect.kernel.Async
import cats.effect.kernel.Resource
import dev.hnaderi.k8s.client.http4s.EmberKubernetesClient
import cats.effect.std.Env
import fs2.io.file.Files
import fs2.io.net.tls.TLSContext
import org.http4s.client.Client

import javax.net.ssl.SSLContext

private[client] trait PlatformCompanion extends JVMPlatform {
self: EmberKubernetesClient with Http4sKubernetesClient =>
private[http4s] abstract class PlatformCompanion[F[_]: Async: Files: Env]
extends JVMPlatform[F] {
self: EmberKubernetesClient[F] =>

override protected def buildWithSSLContext[F[_]: Async]
override protected def buildWithSSLContext
: SSLContext => Resource[F, Client[F]] = ctx =>
buildSecureClient(TLSContext.Builder.forAsync[F].fromSSLContext(ctx))
}
23 changes: 11 additions & 12 deletions modules/http4s-ember/.native/src/main/scala/PlatformCompanion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
*/

package dev.hnaderi.k8s.client
package http4s

import cats.effect.kernel.Async
import cats.effect.kernel.Resource
import cats.effect.std.Env
import cats.syntax.all._
import dev.hnaderi.k8s.client.http4s.EmberKubernetesClient
import dev.hnaderi.k8s.utils._
import fs2.Stream
import fs2.io.file.Files
Expand All @@ -31,9 +32,11 @@ import org.http4s._
import org.http4s.client.Client
import scodec.bits.ByteVector

private[client] trait PlatformCompanion extends Http4sKubernetesClient {
self: EmberKubernetesClient =>
private def dataOrFile[F[_]: Async: Files](
private[http4s] abstract class PlatformCompanion[F[_]: Async: Files: Env]
extends Http4sKubernetesClient[F] {
self: EmberKubernetesClient[F] =>

private def dataOrFile(
data: Option[String],
file: Option[String]
): Resource[F, Option[ByteVector]] =
Expand All @@ -45,7 +48,7 @@ private[client] trait PlatformCompanion extends Http4sKubernetesClient {
.getOrElse(Option.empty.pure)
)

private def client[F[_]: Async: Files](
private def client(
caData: Option[String] = None,
caFile: Option[String],
clientCert: Option[String] = None,
Expand All @@ -67,12 +70,10 @@ private[client] trait PlatformCompanion extends Http4sKubernetesClient {
client <- buildSecureClient(tls)
} yield client

final override def fromConfig[F[_], T](
final override def fromConfig[T](
config: Config,
context: Option[String] = None
)(implicit
F: Async[F],
Files: Files[F],
enc: EntityEncoder[F, T],
dec: EntityDecoder[F, T],
builder: Builder[T],
Expand All @@ -93,7 +94,7 @@ private[client] trait PlatformCompanion extends Http4sKubernetesClient {
).raiseError
)
case Some((cluster, server, auth)) =>
client[F](
client(
caFile = cluster.`certificate-authority`,
caData = cluster.`certificate-authority-data`,
clientCert = auth.`client-certificate-data`,
Expand All @@ -107,16 +108,14 @@ private[client] trait PlatformCompanion extends Http4sKubernetesClient {

}

final override def from[F[_], T](
final override def from[T](
server: String,
ca: Option[Path] = None,
clientCert: Option[Path] = None,
clientKey: Option[Path] = None,
clientKeyPassword: Option[String] = None,
authentication: AuthenticationParams = AuthenticationParams.empty
)(implicit
F: Async[F],
Files: Files[F],
enc: EntityEncoder[F, T],
dec: EntityDecoder[F, T],
builder: Builder[T],
Expand Down
29 changes: 17 additions & 12 deletions modules/http4s-ember/src/main/scala/EmberKubernetesClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,32 @@ package http4s

import cats.effect.kernel.Async
import cats.effect.kernel.Resource
import cats.effect.std.Env
import fs2.io.file.Files
import fs2.io.net.Network
import fs2.io.net.tls.TLSContext
import org.http4s.client.Client
import org.http4s.ember.client.EmberClientBuilder

object EmberKubernetesClient extends EmberKubernetesClient

trait EmberKubernetesClient extends PlatformCompanion {

override protected def buildClient[F[_]: Async]: Resource[F, Client[F]] = {
implicit val net: Network[F] = Network.forAsync[F]
final class EmberKubernetesClient[F[_]: Async: Network: Files: Env] private (
builder: EmberClientBuilder[F]
) extends PlatformCompanion[F] {

override protected def buildClient: Resource[F, Client[F]] =
EmberClientBuilder.default[F].build
}

protected def buildSecureClient[F[_]: Async](
protected def buildSecureClient(
ctx: TLSContext[F]
): Resource[F, Client[F]] = {
implicit val net: Network[F] = Network.forAsync[F]
): Resource[F, Client[F]] = builder.withTLSContext(ctx).build

}

EmberClientBuilder.default[F].withTLSContext(ctx).build
}
object EmberKubernetesClient {
def apply[F[_]: Async: Network: Files: Env]: EmberKubernetesClient[F] =
new EmberKubernetesClient[F](EmberClientBuilder.default[F])

def apply[F[_]: Async: Network: Files: Env](
builder: EmberClientBuilder[F]
): EmberKubernetesClient[F] =
new EmberKubernetesClient[F](builder)
}
Loading