Skip to content

Commit

Permalink
Merge 46edfa3 into a1f35ac
Browse files Browse the repository at this point in the history
  • Loading branch information
rtitle committed Aug 18, 2020
2 parents a1f35ac + 46edfa3 commit 2cc7195
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ To depend on the `MockGoogle*` classes, additionally depend on:

Contains utility functions for talking to Google APIs via com.google.cloud client library (more recent) via gRPC.

Latest SBT dependency: `"org.broadinstitute.dsde.workbench" %% "workbench-google2" % "0.11-ea9bf21"`
Latest SBT dependency: `"org.broadinstitute.dsde.workbench" %% "workbench-google2" % "0.11-TRAVIS-REPLACE-ME"`

To start the Google PubSub emulator for unit testing:

Expand Down
3 changes: 2 additions & 1 deletion google2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ Added:
- Add `detachDisk`
- Add `streamUploadBlob`
- Add `listPodStatus` to `KubernetesService`, returns statuses of all pods belonging to a k8s cluster
- Add `getServiceExternalIp` to `KubernetesService`

SBT dependency: `"org.broadinstitute.dsde.workbench" %% "workbench-google2" % "0.11-ea9bf21"`
SBT dependency: `"org.broadinstitute.dsde.workbench" %% "workbench-google2" % "0.11-TRAVIS-REPLACE-ME"`

## 0.10
Changed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ import java.util.UUID
import java.util.concurrent.TimeUnit

import cats.effect.concurrent.Semaphore
import cats.effect.implicits._
import cats.effect.{Async, Blocker, ContextShift, Effect, Timer}
import io.chrisdavenport.log4cats.StructuredLogger
import org.broadinstitute.dsde.workbench.RetryConfig
import cats.implicits._
import cats.effect.implicits._
import cats.mtl.ApplicativeAsk
import com.google.auth.oauth2.{AccessToken, GoogleCredentials}
import com.google.common.cache.{CacheBuilder, CacheLoader}
import com.google.container.v1.Cluster
import io.chrisdavenport.log4cats.StructuredLogger
import io.kubernetes.client.ApiClient
import io.kubernetes.client.apis.{CoreV1Api, RbacAuthorizationV1Api}
import io.kubernetes.client.util.Config
import org.broadinstitute.dsde.workbench.RetryConfig
import org.broadinstitute.dsde.workbench.google2.GKEModels.KubernetesClusterId
import org.broadinstitute.dsde.workbench.google2.JavaSerializableInstances._
import org.broadinstitute.dsde.workbench.google2.JavaSerializableSyntax._
import org.broadinstitute.dsde.workbench.google2.KubernetesModels._
import org.broadinstitute.dsde.workbench.google2.KubernetesSerializableName.{PodName, ServiceName}
import org.broadinstitute.dsde.workbench.model.TraceId
import JavaSerializableSyntax._
import JavaSerializableInstances._
import org.broadinstitute.dsde.workbench.google2.KubernetesSerializableName.PodName

import scala.collection.JavaConverters._

Expand Down Expand Up @@ -144,6 +144,34 @@ class KubernetesInterpreter[F[_]: Async: StructuredLogger: Effect: Timer: Contex
)
} yield ()

override def getServiceExternalIp(clusterId: KubernetesClusterId,
namespace: KubernetesNamespace,
serviceName: ServiceName)(
implicit ev: ApplicativeAsk[F, TraceId]
): F[Option[ServiceExternalIp]] =
for {
traceId <- ev.ask
client <- blockingF(getClient(clusterId, new CoreV1Api(_)))
call = blockingF(
Async[F].delay(
client.listNamespacedService(namespace.name.value, null, "true", null, null, null, null, null, null, null)
)
)
response <- withLogging(
call,
Some(traceId),
s"io.kubernetes.client.apis.CoreV1Api.listNamespacedService(${namespace.name.value}, null, true, null, null, null, null, null, null, null)"
)

ipOpt = Option(response.getItems).flatMap { items =>
items.asScala
.filter(i => i.getMetadata.getName == serviceName.value)
.flatMap(i => i.getSpec.getExternalIPs.asScala)
.headOption
.map(ServiceExternalIp)
}
} yield ipOpt

override def createNamespace(clusterId: KubernetesClusterId, namespace: KubernetesNamespace)(
implicit ev: ApplicativeAsk[F, TraceId]
): F[Unit] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import io.chrisdavenport.log4cats.StructuredLogger
import org.broadinstitute.dsde.workbench.RetryConfig
import org.broadinstitute.dsde.workbench.google2.GKEModels.KubernetesClusterId
import org.broadinstitute.dsde.workbench.google2.KubernetesModels._
import org.broadinstitute.dsde.workbench.google2.KubernetesSerializableName.ServiceName
import org.broadinstitute.dsde.workbench.google2.util.RetryPredicates
import org.broadinstitute.dsde.workbench.model.TraceId

Expand Down Expand Up @@ -47,6 +48,10 @@ trait KubernetesService[F[_]] {
implicit ev: ApplicativeAsk[F, TraceId]
): F[Unit]

def getServiceExternalIp(clusterId: KubernetesClusterId, namespace: KubernetesNamespace, serviceName: ServiceName)(
implicit ev: ApplicativeAsk[F, TraceId]
): F[Option[ServiceExternalIp]]

def createRole(clusterId: KubernetesClusterId, role: KubernetesRole, namespace: KubernetesNamespace)(
implicit ev: ApplicativeAsk[F, TraceId]
): F[Unit]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package org.broadinstitute.dsde.workbench.google2

import com.google.container.v1.Operation

import collection.JavaConverters._
Expand Down Expand Up @@ -387,17 +388,17 @@ object KubernetesModels {
resourceLimits: Option[Map[String, String]] = None)

sealed trait KubernetesServiceKind extends Product with Serializable {
val SERVICE_TYPE_NODEPORT = KubernetesServiceKindName("NodePort")
val SERVICE_TYPE_LOADBALANCER = KubernetesServiceKindName("LoadBalancer")
val SERVICE_TYPE_CLUSTERIP = KubernetesServiceKindName("ClusterIP")

def kindName: KubernetesServiceKindName
def serviceName: ServiceName
def selector: KubernetesSelector
def ports: Set[ServicePort]
}

object KubernetesServiceKind {
val SERVICE_TYPE_NODEPORT = KubernetesServiceKindName("NodePort")
val SERVICE_TYPE_LOADBALANCER = KubernetesServiceKindName("LoadBalancer")
val SERVICE_TYPE_CLUSTERIP = KubernetesServiceKindName("ClusterIP")

final case class KubernetesLoadBalancerService(selector: KubernetesSelector,
ports: Set[ServicePort],
serviceName: ServiceName)
Expand All @@ -418,7 +419,6 @@ object KubernetesModels {
extends KubernetesServiceKind {
val kindName = SERVICE_TYPE_CLUSTERIP
}

}

final case class ServicePort(num: PortNum, name: PortName, targetPort: TargetPortNum, protocol: Protocol)
Expand All @@ -428,6 +428,8 @@ object KubernetesModels {
final case class PortName(value: String) extends AnyVal
final case class Protocol(value: String) extends AnyVal

final case class ServiceExternalIp(value: String) extends AnyVal

//container ports are primarily informational, not specifying them does not prevent them from being exposed
final case class ContainerPort(value: Int)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ package mock

import cats.effect.IO
import cats.mtl.ApplicativeAsk
import org.broadinstitute.dsde.workbench.google2.KubernetesModels.KubernetesPodStatus
import org.broadinstitute.dsde.workbench.google2.KubernetesSerializableName.PodName
import org.broadinstitute.dsde.workbench.google2.GKEModels.KubernetesClusterId
import org.broadinstitute.dsde.workbench.google2.KubernetesModels.{
KubernetesNamespace,
KubernetesPodStatus,
ServiceExternalIp
}
import org.broadinstitute.dsde.workbench.google2.KubernetesSerializableName.{PodName, ServiceName}
import org.broadinstitute.dsde.workbench.model.TraceId

class MockKubernetesService extends org.broadinstitute.dsde.workbench.google2.KubernetesService[IO] {
Expand Down Expand Up @@ -41,6 +46,12 @@ class MockKubernetesService extends org.broadinstitute.dsde.workbench.google2.Ku
namespace: KubernetesModels.KubernetesNamespace
)(implicit ev: ApplicativeAsk[IO, TraceId]): IO[Unit] = IO.unit

override def getServiceExternalIp(clusterId: KubernetesClusterId,
namespace: KubernetesNamespace,
serviceName: ServiceName)(
implicit ev: ApplicativeAsk[IO, TraceId]
): IO[Option[ServiceExternalIp]] = IO(Some(ServiceExternalIp("1.2.3.4")))

override def createRole(
clusterId: GKEModels.KubernetesClusterId,
role: KubernetesModels.KubernetesRole,
Expand Down

0 comments on commit 2cc7195

Please sign in to comment.