Giter Site home page Giter Site logo

infrastructure-as-types's Introduction

Infrastructure as Types

Version

Logo

Important

The successor of this project is called Besom and uses Pulumi.

Warning

This repository is archived

Infrastructure as Types project provides tools for modern infrastructure declaration and deployment. From simple application deployment script to a complex custom control plane, we'd like to help you write the code you need.

To prioritise our efforts, please feel free to give us feedback as to what do you think we should do next.

You can reach-out to us on GitHub or fill a short anonymous form.

The Audience

We start our journey with an audience of:

  • JVM developer teams
  • At least medium Scala knowledge level
  • Basic Cloud and Kubernetes skills

In current stage, we encourage only experimental usage.

The Problem

With trends of moving complexity of non-functional requirements out of the application code, and creating smaller and smaller micro or even nano-services (?), we need tools to tackle the old and new complexity.

Main problems we want to solve:

  • help manage inherent complexity and avoid accidental complexity
  • address the definition scalability issues of hundreds of interdependent YAMLs
  • allow for refactoring a lot safer than untyped, text heavy YAML
  • effortless security rules, derived from the strongly typed code
  • allow to tackle the complexity that comes with service mesh's and ingress controllers

Vision

Use your programming language to express it all, business logic and non-functional requirements.

We want every JVM developer (starting with Scala) to feel at home in a cloud native environment (starting with Kubernetes).

We believe that a developer friendly infrastructure abstractions are increasingly necessary in the age of the cloud. Bootstrapping and maintaining a distributed system required by a modern business requirements is often challenging and costly. Real-world use cases come with complexity that YAMLs ans JSONs can't reliably express. Strongly typed general purpose programming language, like Scala, is a game changer.

The plan for this PoC is simple, provide a set of tools for micro-service infrastructure development:

  • High-level Scala DSL describing a graph of your (micro)services and their connectivity
  • Low-level Scala DSL for Kubernetes manifest resources (incl. CRDs)
  • YAML/JSON generators

Design considerations:

  • easy to read and maintain code for the users
  • 80% of use cases should be easy and straightforward to express (with high-to-mid-level abstractions)
  • provide many extension points for the remaining 20% of use cases
  • no unnecesary abstractions
  • balance between type-safety and type-magic

Problem classes addressed:

  • error-prone text based references between resources
  • good defaults and examples lower the learning curve
  • familiar tools and language lower the barriers to entry
  • leverage the complexity management and refactoring abilities of Scala
  • basic derivation of network policy rules from high-level definitions

We believe that with more work we could be able to do even more, especially with orchestrating kubernetes and a service mesh.

Additional opportunities and future development ideas:

  • take advantage of Scala 3 unique features
  • even thinner abstraction, more developer friendly
  • deployment and release strategies library (blue-green, canary, A/B, etc.)
  • unit and integrations test frameworks (with dry-run capabilities)
  • control plane development library (e.g. for a service mesh)
  • service-mesh specific features (e.g. xDS support for custom control planes)
  • serverless library (e.g. support for Knative)
  • sbt plugin and REPL e.g. Ammonite
  • native container image support (e.g. GraalVM)
  • self-deployment pattern support
  • Kotlin support

Kubernetes

The first backend we provide is the Kubernetes API.

Fragments of classic GuestBook example with added Network Policy:

val guestbook = Namespace(Name("guestbook") :: Nil)

val frontend = Application(
  Name("frontend") :: App("guestbook") :: Tier("frontend") :: Nil,
  Container(
    Name("php-redis") :: Nil,
    image = "gcr.io/google-samples/gb-frontend:v4",
    ports = TCP(80) :: Nil,
    envs = "GET_HOSTS_FROM" -> "dns" :: Nil
  ) :: Nil
)

val redisMaster = Application(
  Name("redis-master") :: App("redis") :: Role("master") :: Tier("backend") :: Nil,
  Container(
    Name("master") :: Nil,
    image = "k8s.gcr.io/redis:e2e",
    ports = TCP(6379) :: Nil
  ) :: Nil
)

import iat.kubernetes.dsl.NetworkPolicy.ops._

val connFrontRedis = frontend
  .communicatesWith(redisMaster)
  .egressOnly
  .labeled(Name("front-redis") :: App("guestbook") :: Nil)
val connFrontDns = frontend
  .communicatesWith(NetworkPolicy.peer.kubernetesDns)
  .egressOnly
  .named("front-k8s-dns")

import iat.skuber.deployment._
import skuber.json.format._

val ns: Seq[Summary] =
  guestbook.interpret.upsertBlocking().summary :: Nil
val apps: Seq[Summary] = List(
  redisMaster
    .interpretWith(guestbook)
    .map(redisMasterDetails),
  redisSlave
    .interpretWith(guestbook)
    .map(redisSlaveDetails),
  frontend
    .interpretWith(guestbook)
    .map(frontendDetails)
  ).flatMap(_.upsertBlocking().summary)

val conns: Seq[Summary] = List(
  NetworkPolicy.default.denyAll.interpretWith(guestbook),
  connExtFront.interpretWith(guestbook),
  connFrontRedis.interpretWith(guestbook),
  connRedisMS.interpretWith(guestbook),
  connRedisSM.interpretWith(guestbook),
  connFrontDns.interpretWith(guestbook),
  connRedisSlaveDns.interpretWith(guestbook)
).map(_.upsertBlocking().summary)

See the full GuestBook example here. For a different flavour, see the same applications but materialized into JSON/YAML.

Core concepts

The basic concepts in the Infrastructure as Types high-level graphs are Label, Protocol and Identity, and, of course, types.

Label, protocol, identity

A label is a simple key/value pair. Can be used for grouping, selection or informational purposes.

trait Labeled {
  def labels: List[Label]
}

trait Label {
  def key: String
  def value: String
}

Protocols are stacked in Layers. For more details see Protocol and Protocols.

trait Protocol

object Protocol {
  trait Layer7 extends Protocol
  trait Layer4 extends Protocol
  trait Layer3 extends Protocol

  trait Layers[L7 <: Protocol.Layer7, L4 <: Protocol.Layer4, L3 <: Protocol.Layer3] {
    def l7: L7
    def l4: L4
    def l3: L3
  }

  trait IP extends Protocol.Layer3 with HasCidr
  trait UDP extends Protocol.Layer4 with HasPort
  trait TCP extends Protocol.Layer4 with HasPort

  trait HTTP extends Protocol.L7 {
    def method: HTTP.Method
    def path: HTTP.Path
    def host: HTTP.Host
  }
}

Peer and Selection

Type, expressions, protocols and identities for a node of the connectivity graph. Peer is a connectivity graph node that is instance of type A. Selection is a connectivity graph node of type A and no instance.

trait Peer[A] extends Reference[A] with Selection[A] { self: A =>
}

trait Selection[A] {
  def expressions: Expressions
  def protocols: Protocols
  def identities: Identities
}

trait Reference[A] { self: A =>
  def reference: A = self
}

Extension points

There are many extension points provided to enable extension and customization.

Interpretable

The most important extension point is the Interpretable trait. It is a type that can be interpreted to some form of output.

trait Interpretable[A] extends Reference[A] { self: A =>
}

Interpretable[A] types get their implementation specific methods from an implicit class, e.g.:

implicit class SecretInterpretationOps(val obj: Secret) 
  extends InterpreterOps1[Secret, Namespace, model.Secret]

It adds interpretWith method that take an implementation specific context C (Namespace) and implicit function from A (Secret) and C to some B1 (model.Secret).

trait InterpreterOps1[A, C, B1 <: Base] {
  def obj: Interpretable[A]
  def interpretWith(
      ctx: C
    )(implicit
      interpreter: (A, C) => B1
    ): B1 = interpreter(obj.reference, ctx)
}

See core/InterpreterOps for details.

The Interpretable[A] and InterpreterOpsX combined, give essentially the ability to go from a Kubernetes DSL Secret and Namespace to Kubernetes API model.Secret.

This mechanism gives the flexibility to:

  • change the implementation (and the materialized output) with a simple import
  • override the implicit interpreter at the interpretWith call-site
  • easily implement a custom interpreter and use a type or only an instance

On the downside, it adds an abstraction layer, so we may remove it in the future and scrafice generality for usability.

Moreover, the returned type B1 extends an implementation specific Base type. As a consequence, another implicit class can be added to the chain, e.g.:

type Base = ApiModel

implicit class ApiModelOps1[A <: Base](a: A) {
    def asJValues(implicit formats: Formats): List[JValue] = ???
}

This allows for interesting use cases, e.g.:

app                 // an application 'app'
  .interpret(ns)    // interpreted into a namespace 'ns'
  .map(appDetails)  // with a modified interpreter output (low level API)
  .upsertBlocking() // created or updated on a cluster
  .deinterpret      // de-interpreted back into high level API
  .summary          // summarize the difference between applied and defined 'app' 

Patchable

Patchable type is a simple convenience method to enable changes to the immutable types.

trait Patchable[A] { self: A =>
  def patch(f: A => A): A = f(self)
}

This is especially useful to express differences in the runtime environments (e.g. dev vs prod).

Status

The project is in alpha and under heavy development, any and all APIs can change without notice.

API/Technology Status
kubernetes alpha
istio -
linkerd -
envoy -
knative -
Kubernetes Client Status
skuber alpha
OpenAPI / sttp experimental
Use case Status
JSON/YAML generation alpha
Kubernetes Deployment experimental
JSON/YAML diff -
Kubernetes Operator -
Unit and integration tests basic

Community & Contribution

There is a dedicated channel #infrastructure-as-types on virtuslab-oss.slack.com (Invite form)

Feel free to file issues or pull requests.

Before any big pull request please consult the maintainers to ensure a common direction.

Development

The project is a standard Scala/sbt project. Examples require a Kubernetes API access (~/.kube/config).

Test cluster config is available with (available only internally):

gcloud container clusters get-credentials standard-cluster-1 --zone us-central1-a --project infrastructure-as-types

infrastructure-as-types's People

Contributors

gryfit avatar lbialy avatar pawellipski avatar pawelprazak avatar szymon-rd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

infrastructure-as-types's Issues

Apply a static code analyzer

We used https://github.com/wartremover/wartremover in the previous project:

wartremoverWarnings in (Compile, compile) := {
      import Wart._
      Seq(AnyVal, ArrayEquals, EitherProjectionPartial, FinalCaseClass, IsInstanceOf, JavaConversions,
        LeakingSealed, NonUnitStatements, Null, Recursion, Return, StringPlusAny, ToString)
    },

TBD: possibly better/more suitable alternatives exist.

Await readiness of deployed resources

An option in that would act like helm upgrade --wait (wait until deployed resources are ready) would be useful.

Using kubectl wait for that purpose is kinda hard to scale (did I remember to wait on all deployed resources)?

Service update brakes on spec.clusterIP, Invalid value: field is immutable

As for now, running GuestBook for second time yields:

2020-06-26T13:32:18.4859902Z > Task :deployToKubernetesCluster
2020-06-26T13:32:18.4861178Z [INFO] [06/26/2020 13:32:17.951] [main] [skuber.api] Using following context for connecting to Kubernetes cluster: Context(Cluster(v1,***,false,Some(Right([B@2ce6c6ec))),CertAuth(clientCertificate=<PEM masked> clientKey=<PEM masked> userName= ),Namespace(Namespace,v1,ObjectMeta(default,,,,,,None,None,None,Map(),Map(),List(),0,None,None),None,None))
2020-06-26T13:32:19.4831095Z [INFO] [06/26/2020 13:32:19.471] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/api/v1/namespaces]
2020-06-26T13:32:20.4824033Z [INFO] [06/26/2020 13:32:20.424] [a-system-akka.actor.default-dispatcher-6] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:20.4825863Z [INFO] [06/26/2020 13:32:20.457] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(namespaces "guestbook" already exists),Some(AlreadyExists),Some({"name":"guestbook","kind":"namespaces"}),Some(409))
2020-06-26T13:32:20.4827079Z [INFO] [06/26/2020 13:32:20.467] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/api/v1/namespaces/guestbook]
2020-06-26T13:32:20.5821617Z [INFO] [06/26/2020 13:32:20.563] [a-system-akka.actor.default-dispatcher-5] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:20.6837874Z Successfully created or updated 'Namespace(Namespace,v1,ObjectMeta(guestbook,,,e67fd532-b227-11ea-9e76-42010a9c0083,/api/v1/namespaces/guestbook,1908,Some(2020-06-19T12:25:02Z),None,None,Map(name -> guestbook),Map(),List(),0,None,None),Some(Spec(Some(List(kubernetes)))),Some(Status(Active)))' on Kubernetes cluster
2020-06-26T13:32:21.7823863Z [INFO] [06/26/2020 13:32:21.675] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/api/v1/namespaces/guestbook/services]
2020-06-26T13:32:21.8824407Z [INFO] [06/26/2020 13:32:21.785] [a-system-akka.actor.default-dispatcher-17] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:21.8825887Z [INFO] [06/26/2020 13:32:21.786] [a-system-akka.actor.default-dispatcher-2] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(services "redis-master" already exists),Some(AlreadyExists),Some({"name":"redis-master","kind":"services"}),Some(409))
2020-06-26T13:32:21.8827583Z [INFO] [06/26/2020 13:32:21.789] [a-system-akka.actor.default-dispatcher-2] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/api/v1/namespaces/guestbook/services/redis-master]
2020-06-26T13:32:21.9825015Z [INFO] [06/26/2020 13:32:21.884] [a-system-akka.actor.default-dispatcher-3] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 422]
2020-06-26T13:32:21.9828488Z [INFO] [06/26/2020 13:32:21.886] [a-system-akka.actor.default-dispatcher-2] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(Service "redis-master" is invalid: [metadata.resourceVersion: Invalid value: "": must be specified for an update, spec.clusterIP: Invalid value: "": field is immutable]),Some(Invalid),Some({"name":"redis-master","kind":"Service","causes":[{"reason":"FieldValueInvalid","message":"Invalid value: \"\": must be specified for an update","field":"metadata.resourceVersion"},{"reason":"FieldValueInvalid","message":"Invalid value: \"\": must be specified for an update","field":"metadata.resourceVersion"},{"reason":"FieldValueInvalid","message":"Invalid value: \"\": field is immutable","field":"spec.clusterIP"}]}),Some(422))
2020-06-26T13:32:21.9831078Z [INFO] [06/26/2020 13:32:21.898] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/apps/v1/namespaces/guestbook/deployments]
2020-06-26T13:32:22.0823075Z [INFO] [06/26/2020 13:32:21.993] [a-system-akka.actor.default-dispatcher-3] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:22.0824801Z [INFO] [06/26/2020 13:32:21.994] [a-system-akka.actor.default-dispatcher-6] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(deployments.apps "redis-master" already exists),Some(AlreadyExists),Some({"name":"redis-master","group":"apps","kind":"deployments"}),Some(409))
2020-06-26T13:32:22.0826563Z [INFO] [06/26/2020 13:32:22.001] [a-system-akka.actor.default-dispatcher-6] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/apps/v1/namespaces/guestbook/deployments/redis-master]
2020-06-26T13:32:22.1822193Z [INFO] [06/26/2020 13:32:22.102] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:22.1825096Z Successfully created or updated 'Deployment(Deployment,apps/v1,ObjectMeta(redis-master,,guestbook,e77a8807-b227-11ea-9e76-42010a9c0083,/apis/apps/v1/namespaces/guestbook/deployments/redis-master,2124331,Some(2020-06-19T12:25:04Z),None,None,Map(app -> redis, name -> redis-master, role -> master, tier -> backend),Map(),List(),4,None,None),Some(Spec(Some(1),app=redis,name=redis-master,role=master,tier=backend,Spec(ObjectMeta(,,,,,,None,None,None,Map(app -> redis, name -> redis-master, role -> master, tier -> backend),Map(),List(),0,None,None),Some(Spec(List(Container(master,k8s.gcr.io/redis:e2e,List(),List(),None,List(Port(6379,TCP,,,None)),List(),Some(Requirements(Map(),Map(cpu -> 100m, memory -> 100Mi))),List(),None,None,None,Some(/dev/termination-log),Some(File),IfNotPresent,None,List(),None,None,None,List())),List(),List(),Always,Some(30),None,ClusterFirst,Map(),,,false,List(),None,List(),Some(PodSecurityContext(None,None,None,None,None,List(),List())),None,List(),None,None,None,None,None,Some(default-scheduler),None,None,None))),Some(StrategyImpl(RollingUpdate,Some(RollingUpdate(Right(25%),Right(25%))))),0,Some(10),false,Some(600))),Some(Status(1,1,1,1,0,3,None,List(Condition(Available,True,Some(2020-06-19T12:25:24Z),Some(2020-06-19T12:25:24Z),Some(MinimumReplicasAvailable),Some(Deployment has minimum availability.)), Condition(Progressing,True,Some(2020-06-19T12:25:24Z),Some(2020-06-19T12:25:04Z),Some(NewReplicaSetAvailable),Some(ReplicaSet "redis-master-85ffb4f89" has successfully progressed.))))))' on Kubernetes cluster
2020-06-26T13:32:22.1826979Z [INFO] [06/26/2020 13:32:22.157] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/api/v1/namespaces/guestbook/services]
2020-06-26T13:32:22.2823056Z [INFO] [06/26/2020 13:32:22.262] [a-system-akka.actor.default-dispatcher-2] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(services "redis-slave" already exists),Some(AlreadyExists),Some({"name":"redis-slave","kind":"services"}),Some(409))
2020-06-26T13:32:22.2825108Z [INFO] [06/26/2020 13:32:22.265] [a-system-akka.actor.default-dispatcher-2] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/api/v1/namespaces/guestbook/services/redis-slave]
2020-06-26T13:32:22.2826044Z [INFO] [06/26/2020 13:32:22.267] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:22.3825093Z [INFO] [06/26/2020 13:32:22.360] [a-system-akka.actor.default-dispatcher-6] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 422]
2020-06-26T13:32:22.3837230Z [INFO] [06/26/2020 13:32:22.362] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(Service "redis-slave" is invalid: [metadata.resourceVersion: Invalid value: "": must be specified for an update, spec.clusterIP: Invalid value: "": field is immutable]),Some(Invalid),Some({"name":"redis-slave","kind":"Service","causes":[{"reason":"FieldValueInvalid","message":"Invalid value: \"\": must be specified for an update","field":"metadata.resourceVersion"},{"reason":"FieldValueInvalid","message":"Invalid value: \"\": must be specified for an update","field":"metadata.resourceVersion"},{"reason":"FieldValueInvalid","message":"Invalid value: \"\": field is immutable","field":"spec.clusterIP"}]}),Some(422))
2020-06-26T13:32:22.3838813Z [INFO] [06/26/2020 13:32:22.367] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/apps/v1/namespaces/guestbook/deployments]
2020-06-26T13:32:22.4824194Z [INFO] [06/26/2020 13:32:22.463] [a-system-akka.actor.default-dispatcher-17] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:22.4825403Z [INFO] [06/26/2020 13:32:22.464] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(deployments.apps "redis-slave" already exists),Some(AlreadyExists),Some({"name":"redis-slave","group":"apps","kind":"deployments"}),Some(409))
2020-06-26T13:32:22.4826774Z [INFO] [06/26/2020 13:32:22.467] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/apps/v1/namespaces/guestbook/deployments/redis-slave]
2020-06-26T13:32:22.5822756Z [INFO] [06/26/2020 13:32:22.565] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:22.5825886Z Successfully created or updated 'Deployment(Deployment,apps/v1,ObjectMeta(redis-slave,,guestbook,e7a7ee23-b227-11ea-9e76-42010a9c0083,/apis/apps/v1/namespaces/guestbook/deployments/redis-slave,2124339,Some(2020-06-19T12:25:04Z),None,None,Map(app -> redis, name -> redis-slave, role -> slave, tier -> backend),Map(),List(),4,None,None),Some(Spec(Some(2),app=redis,name=redis-slave,role=slave,tier=backend,Spec(ObjectMeta(,,,,,,None,None,None,Map(app -> redis, name -> redis-slave, role -> slave, tier -> backend),Map(),List(),0,None,None),Some(Spec(List(Container(slave,gcr.io/google_samples/gb-redisslave:v3,List(),List(),None,List(Port(6379,TCP,,,None)),List(EnvVar(GET_HOSTS_FROM,StringValue(dns))),Some(Requirements(Map(),Map(cpu -> 100m, memory -> 100Mi))),List(),None,None,None,Some(/dev/termination-log),Some(File),IfNotPresent,None,List(),None,None,None,List())),List(),List(),Always,Some(30),None,ClusterFirst,Map(),,,false,List(),None,List(),Some(PodSecurityContext(None,None,None,None,None,List(),List())),None,List(),None,None,None,None,None,Some(default-scheduler),None,None,None))),Some(StrategyImpl(RollingUpdate,Some(RollingUpdate(Right(25%),Right(25%))))),0,Some(10),false,Some(600))),Some(Status(2,2,2,2,0,3,None,List(Condition(Available,True,Some(2020-06-19T12:25:34Z),Some(2020-06-19T12:25:34Z),Some(MinimumReplicasAvailable),Some(Deployment has minimum availability.)), Condition(Progressing,True,Some(2020-06-19T12:25:34Z),Some(2020-06-19T12:25:04Z),Some(NewReplicaSetAvailable),Some(ReplicaSet "redis-slave-86c7c787f8" has successfully progressed.))))))' on Kubernetes cluster
2020-06-26T13:32:22.6823536Z [INFO] [06/26/2020 13:32:22.579] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/api/v1/namespaces/guestbook/services]
2020-06-26T13:32:22.7823279Z [INFO] [06/26/2020 13:32:22.684] [a-system-akka.actor.default-dispatcher-5] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:22.7824868Z [INFO] [06/26/2020 13:32:22.685] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(services "frontend" already exists),Some(AlreadyExists),Some({"name":"frontend","kind":"services"}),Some(409))
2020-06-26T13:32:22.7826476Z [INFO] [06/26/2020 13:32:22.689] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/api/v1/namespaces/guestbook/services/frontend]
2020-06-26T13:32:22.8821872Z [INFO] [06/26/2020 13:32:22.783] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 422]
2020-06-26T13:32:22.8824057Z [INFO] [06/26/2020 13:32:22.784] [a-system-akka.actor.default-dispatcher-2] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(Service "frontend" is invalid: [metadata.resourceVersion: Invalid value: "": must be specified for an update, spec.clusterIP: Invalid value: "": field is immutable]),Some(Invalid),Some({"name":"frontend","kind":"Service","causes":[{"reason":"FieldValueInvalid","message":"Invalid value: \"\": must be specified for an update","field":"metadata.resourceVersion"},{"reason":"FieldValueInvalid","message":"Invalid value: \"\": must be specified for an update","field":"metadata.resourceVersion"},{"reason":"FieldValueInvalid","message":"Invalid value: \"\": field is immutable","field":"spec.clusterIP"}]}),Some(422))
2020-06-26T13:32:22.8826301Z [INFO] [06/26/2020 13:32:22.787] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/apps/v1/namespaces/guestbook/deployments]
2020-06-26T13:32:22.9823529Z [INFO] [06/26/2020 13:32:22.884] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:22.9825204Z [INFO] [06/26/2020 13:32:22.884] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(deployments.apps "frontend" already exists),Some(AlreadyExists),Some({"name":"frontend","group":"apps","kind":"deployments"}),Some(409))
2020-06-26T13:32:22.9827157Z [INFO] [06/26/2020 13:32:22.887] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/apps/v1/namespaces/guestbook/deployments/frontend]
2020-06-26T13:32:23.0823345Z [INFO] [06/26/2020 13:32:22.985] [a-system-akka.actor.default-dispatcher-3] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:23.0827586Z Successfully created or updated 'Deployment(Deployment,apps/v1,ObjectMeta(frontend,,guestbook,e7d130bf-b227-11ea-9e76-42010a9c0083,/apis/apps/v1/namespaces/guestbook/deployments/frontend,2124349,Some(2020-06-19T12:25:05Z),None,None,Map(app -> guestbook, name -> frontend, tier -> frontend),Map(),List(),4,None,None),Some(Spec(Some(3),app=guestbook,name=frontend,tier=frontend,Spec(ObjectMeta(,,,,,,None,None,None,Map(app -> guestbook, name -> frontend, tier -> frontend),Map(),List(),0,None,None),Some(Spec(List(Container(php-redis,gcr.io/google-samples/gb-frontend:v4,List(),List(),None,List(Port(80,TCP,,,None)),List(EnvVar(GET_HOSTS_FROM,StringValue(dns))),Some(Requirements(Map(),Map(cpu -> 100m, memory -> 100Mi))),List(),None,None,None,Some(/dev/termination-log),Some(File),IfNotPresent,None,List(),None,None,None,List())),List(),List(),Always,Some(30),None,ClusterFirst,Map(),,,false,List(),None,List(),Some(PodSecurityContext(None,None,None,None,None,List(),List())),None,List(),None,None,None,None,None,Some(default-scheduler),None,None,None))),Some(StrategyImpl(RollingUpdate,Some(RollingUpdate(Right(25%),Right(25%))))),0,Some(10),false,Some(600))),Some(Status(3,3,3,3,0,3,None,List(Condition(Available,True,Some(2020-06-19T12:25:55Z),Some(2020-06-19T12:25:55Z),Some(MinimumReplicasAvailable),Some(Deployment has minimum availability.)), Condition(Progressing,True,Some(2020-06-19T12:25:55Z),Some(2020-06-19T12:25:05Z),Some(NewReplicaSetAvailable),Some(ReplicaSet "frontend-df88649f7" has successfully progressed.))))))' on Kubernetes cluster
2020-06-26T13:32:23.0831685Z [INFO] [06/26/2020 13:32:23.013] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies]
2020-06-26T13:32:23.1824168Z [INFO] [06/26/2020 13:32:23.109] [a-system-akka.actor.default-dispatcher-5] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:23.1826470Z [INFO] [06/26/2020 13:32:23.111] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(networkpolicies.networking.k8s.io "default-deny-all" already exists),Some(AlreadyExists),Some({"name":"default-deny-all","group":"networking.k8s.io","kind":"networkpolicies"}),Some(409))
2020-06-26T13:32:23.1829108Z [INFO] [06/26/2020 13:32:23.114] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/default-deny-all]
2020-06-26T13:32:23.2823085Z [INFO] [06/26/2020 13:32:23.210] [a-system-akka.actor.default-dispatcher-5] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:23.2824794Z Successfully created or updated 'NetworkPolicy(NetworkPolicy,networking.k8s.io/v1,ObjectMeta(default-deny-all,,guestbook,e7e62ac2-b227-11ea-9e76-42010a9c0083,/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/default-deny-all,1980,Some(2020-06-19T12:25:05Z),None,None,Map(name -> default-deny-all),Map(),List(),1,None,None),Some(Spec(,List(),List(),List(Ingress, Egress))))' on Kubernetes cluster
2020-06-26T13:32:23.2826465Z [INFO] [06/26/2020 13:32:23.220] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies]
2020-06-26T13:32:23.3823698Z [INFO] [06/26/2020 13:32:23.316] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:23.3826158Z [INFO] [06/26/2020 13:32:23.316] [a-system-akka.actor.default-dispatcher-3] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(networkpolicies.networking.k8s.io "external-frontend" already exists),Some(AlreadyExists),Some({"name":"external-frontend","group":"networking.k8s.io","kind":"networkpolicies"}),Some(409))
2020-06-26T13:32:23.3829071Z [INFO] [06/26/2020 13:32:23.319] [a-system-akka.actor.default-dispatcher-3] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/external-frontend]
2020-06-26T13:32:23.4823703Z [INFO] [06/26/2020 13:32:23.413] [a-system-akka.actor.default-dispatcher-5] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:23.4826554Z Successfully created or updated 'NetworkPolicy(NetworkPolicy,networking.k8s.io/v1,ObjectMeta(external-frontend,,guestbook,e800ce67-b227-11ea-9e76-42010a9c0083,/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/external-frontend,1985,Some(2020-06-19T12:25:05Z),None,None,Map(name -> external-frontend),Map(),List(),1,None,None),Some(Spec(app=guestbook,name=frontend,tier=frontend,List(IngressRule(List(Port(Left(80),TCP)),List(Peer(None,None,Some(IPBlock(0.0.0.0/0,List())))))),List(),List(Ingress))))' on Kubernetes cluster
2020-06-26T13:32:23.4829055Z [INFO] [06/26/2020 13:32:23.420] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies]
2020-06-26T13:32:23.5822748Z [INFO] [06/26/2020 13:32:23.515] [a-system-akka.actor.default-dispatcher-3] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:23.5824836Z [INFO] [06/26/2020 13:32:23.517] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(networkpolicies.networking.k8s.io "front-redis" already exists),Some(AlreadyExists),Some({"name":"front-redis","group":"networking.k8s.io","kind":"networkpolicies"}),Some(409))
2020-06-26T13:32:23.5827323Z [INFO] [06/26/2020 13:32:23.520] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/front-redis]
2020-06-26T13:32:23.6822603Z [INFO] [06/26/2020 13:32:23.618] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:23.6824165Z Successfully created or updated 'NetworkPolicy(NetworkPolicy,networking.k8s.io/v1,ObjectMeta(front-redis,,guestbook,e80c977a-b227-11ea-9e76-42010a9c0083,/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/front-redis,1986,Some(2020-06-19T12:25:05Z),None,None,Map(app -> guestbook, name -> front-redis),Map(),List(),1,None,None),Some(Spec(app=guestbook,name=frontend,tier=frontend,List(),List(EgressRule(List(Port(Left(6379),TCP)),List(Peer(Some(app=redis,name=redis-master,role=master,tier=backend),None,None)))),List(Egress))))' on Kubernetes cluster
2020-06-26T13:32:23.6831382Z [INFO] [06/26/2020 13:32:23.625] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies]
2020-06-26T13:32:23.7825492Z [INFO] [06/26/2020 13:32:23.720] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:23.7827672Z [INFO] [06/26/2020 13:32:23.721] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(networkpolicies.networking.k8s.io "redis-master-slave" already exists),Some(AlreadyExists),Some({"name":"redis-master-slave","group":"networking.k8s.io","kind":"networkpolicies"}),Some(409))
2020-06-26T13:32:23.7830870Z [INFO] [06/26/2020 13:32:23.724] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/redis-master-slave]
2020-06-26T13:32:23.8823984Z [INFO] [06/26/2020 13:32:23.818] [a-system-akka.actor.default-dispatcher-17] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:23.8826387Z Successfully created or updated 'NetworkPolicy(NetworkPolicy,networking.k8s.io/v1,ObjectMeta(redis-master-slave,,guestbook,e81990cb-b227-11ea-9e76-42010a9c0083,/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/redis-master-slave,1987,Some(2020-06-19T12:25:05Z),None,None,Map(app -> guestbook, name -> redis-master-slave),Map(),List(),1,None,None),Some(Spec(app=redis,name=redis-master,role=master,tier=backend,List(IngressRule(List(Port(Left(6379),TCP)),List(Peer(Some(app=redis,name=redis-slave,role=slave,tier=backend),None,None)))),List(EgressRule(List(Port(Left(6379),TCP)),List(Peer(Some(app=redis,name=redis-slave,role=slave,tier=backend),None,None)))),List(Ingress, Egress))))' on Kubernetes cluster
2020-06-26T13:32:23.8829735Z [INFO] [06/26/2020 13:32:23.824] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies]
2020-06-26T13:32:23.9823865Z [INFO] [06/26/2020 13:32:23.919] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:23.9826513Z [INFO] [06/26/2020 13:32:23.919] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(networkpolicies.networking.k8s.io "redis-slave-master" already exists),Some(AlreadyExists),Some({"name":"redis-slave-master","group":"networking.k8s.io","kind":"networkpolicies"}),Some(409))
2020-06-26T13:32:23.9828526Z [INFO] [06/26/2020 13:32:23.921] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/redis-slave-master]
2020-06-26T13:32:24.0829491Z [INFO] [06/26/2020 13:32:24.016] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:24.0831857Z Successfully created or updated 'NetworkPolicy(NetworkPolicy,networking.k8s.io/v1,ObjectMeta(redis-slave-master,,guestbook,e826706a-b227-11ea-9e76-42010a9c0083,/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/redis-slave-master,1988,Some(2020-06-19T12:25:05Z),None,None,Map(app -> guestbook, name -> redis-slave-master),Map(),List(),1,None,None),Some(Spec(app=redis,name=redis-slave,role=slave,tier=backend,List(IngressRule(List(Port(Left(6379),TCP)),List(Peer(Some(app=redis,name=redis-master,role=master,tier=backend),None,None)))),List(EgressRule(List(Port(Left(6379),TCP)),List(Peer(Some(app=redis,name=redis-master,role=master,tier=backend),None,None)))),List(Ingress, Egress))))' on Kubernetes cluster
2020-06-26T13:32:24.0833739Z [INFO] [06/26/2020 13:32:24.021] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies]
2020-06-26T13:32:24.1824148Z [INFO] [06/26/2020 13:32:24.116] [a-system-akka.actor.default-dispatcher-17] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:24.1826761Z [INFO] [06/26/2020 13:32:24.117] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(networkpolicies.networking.k8s.io "front-k8s-dns" already exists),Some(AlreadyExists),Some({"name":"front-k8s-dns","group":"networking.k8s.io","kind":"networkpolicies"}),Some(409))
2020-06-26T13:32:24.1829501Z [INFO] [06/26/2020 13:32:24.121] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/front-k8s-dns]
2020-06-26T13:32:24.2823847Z [INFO] [06/26/2020 13:32:24.215] [a-system-akka.actor.default-dispatcher-4] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:24.2827037Z Successfully created or updated 'NetworkPolicy(NetworkPolicy,networking.k8s.io/v1,ObjectMeta(front-k8s-dns,,guestbook,e830c8ce-b227-11ea-9e76-42010a9c0083,/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/front-k8s-dns,1989,Some(2020-06-19T12:25:05Z),None,None,Map(name -> front-k8s-dns),Map(),List(),1,None,None),Some(Spec(app=guestbook,name=frontend,tier=frontend,List(),List(EgressRule(List(Port(Left(53),UDP), Port(Left(53),TCP)),List(Peer(None,Some(name=kube-system),None)))),List(Egress))))' on Kubernetes cluster
2020-06-26T13:32:24.2833216Z [INFO] [06/26/2020 13:32:24.219] [main] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: POST ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies]
2020-06-26T13:32:24.3823811Z [INFO] [06/26/2020 13:32:24.314] [a-system-akka.actor.default-dispatcher-2] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 409]
2020-06-26T13:32:24.3826063Z [INFO] [06/26/2020 13:32:24.315] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [Response: non-ok status returned - Status(v1,Status,ListMeta(,,None),Some(Failure),Some(networkpolicies.networking.k8s.io "redis-slave-k8s-dns" already exists),Some(AlreadyExists),Some({"name":"redis-slave-k8s-dns","group":"networking.k8s.io","kind":"networkpolicies"}),Some(409))
2020-06-26T13:32:24.3828030Z [INFO] [06/26/2020 13:32:24.317] [a-system-akka.actor.default-dispatcher-18] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - about to send HTTP request: PUT ***/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/redis-slave-k8s-dns]
2020-06-26T13:32:24.4855995Z [INFO] [06/26/2020 13:32:24.415] [a-system-akka.actor.default-dispatcher-19] [skuber.api] [ { reqId=ae5e6471-b89b-49d7-96b5-98a62873a0cc} } - received response with HTTP status 200]
2020-06-26T13:32:24.4857724Z Successfully created or updated 'NetworkPolicy(NetworkPolicy,networking.k8s.io/v1,ObjectMeta(redis-slave-k8s-dns,,guestbook,e83d1da0-b227-11ea-9e76-42010a9c0083,/apis/networking.k8s.io/v1/namespaces/guestbook/networkpolicies/redis-slave-k8s-dns,1990,Some(2020-06-19T12:25:05Z),None,None,Map(name -> redis-slave-k8s-dns),Map(),List(),1,None,None),Some(Spec(app=redis,name=redis-slave,role=slave,tier=backend,List(),List(EgressRule(List(Port(Left(53),UDP), Port(Left(53),TCP)),List(Peer(None,Some(name=kube-system),None)))),List(Egress))))' on Kubernetes cluster
2020-06-26T13:32:24.4858489Z OK: 'skuber.Namespace' labeled: 'name: guestbook'
2020-06-26T13:32:24.4859053Z Error[422]: 'skuber.Service', details:
2020-06-26T13:32:24.4859570Z ---
2020-06-26T13:32:24.4859933Z apiVersion: "v1"
2020-06-26T13:32:24.4860379Z kind: "Status"
2020-06-26T13:32:24.4860702Z metadata: {}
2020-06-26T13:32:24.4861012Z status: "Failure"
2020-06-26T13:32:24.4861548Z message: "Service \"redis-master\" is invalid: [metadata.resourceVersion: Invalid\
2020-06-26T13:32:24.4861965Z   \ value: \"\": must be specified for an update, spec.clusterIP: Invalid value: \"\
2020-06-26T13:32:24.4862323Z   \": field is immutable]"
2020-06-26T13:32:24.4862638Z reason: "Invalid"
2020-06-26T13:32:24.4862959Z details:
2020-06-26T13:32:24.4863413Z   name: "redis-master"
2020-06-26T13:32:24.4863748Z   kind: "Service"
2020-06-26T13:32:24.4864088Z   causes:
2020-06-26T13:32:24.4864555Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4864911Z     message: "Invalid value: \"\": must be specified for an update"
2020-06-26T13:32:24.4865269Z     field: "metadata.resourceVersion"
2020-06-26T13:32:24.4865745Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4866098Z     message: "Invalid value: \"\": must be specified for an update"
2020-06-26T13:32:24.4866458Z     field: "metadata.resourceVersion"
2020-06-26T13:32:24.4866931Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4867287Z     message: "Invalid value: \"\": field is immutable"
2020-06-26T13:32:24.4867822Z     field: "spec.clusterIP"
2020-06-26T13:32:24.4868165Z code: 422
2020-06-26T13:32:24.4868931Z OK: 'skuber.apps.v1.Deployment' labeled: 'app: redis, name: redis-master, role: master, tier: backend'
2020-06-26T13:32:24.4869525Z Error[422]: 'skuber.Service', details:
2020-06-26T13:32:24.4869984Z ---
2020-06-26T13:32:24.4870308Z apiVersion: "v1"
2020-06-26T13:32:24.4870634Z kind: "Status"
2020-06-26T13:32:24.4870943Z metadata: {}
2020-06-26T13:32:24.4871248Z status: "Failure"
2020-06-26T13:32:24.4871804Z message: "Service \"redis-slave\" is invalid: [metadata.resourceVersion: Invalid value:\
2020-06-26T13:32:24.4872211Z   \ \"\": must be specified for an update, spec.clusterIP: Invalid value: \"\": field\
2020-06-26T13:32:24.4872551Z   \ is immutable]"
2020-06-26T13:32:24.4872876Z reason: "Invalid"
2020-06-26T13:32:24.4873194Z details:
2020-06-26T13:32:24.4873640Z   name: "redis-slave"
2020-06-26T13:32:24.4874277Z   kind: "Service"
2020-06-26T13:32:24.4874604Z   causes:
2020-06-26T13:32:24.4880420Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4880748Z     message: "Invalid value: \"\": must be specified for an update"
2020-06-26T13:32:24.4880945Z     field: "metadata.resourceVersion"
2020-06-26T13:32:24.4881402Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4881607Z     message: "Invalid value: \"\": must be specified for an update"
2020-06-26T13:32:24.4881804Z     field: "metadata.resourceVersion"
2020-06-26T13:32:24.4882121Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4882328Z     message: "Invalid value: \"\": field is immutable"
2020-06-26T13:32:24.4882506Z     field: "spec.clusterIP"
2020-06-26T13:32:24.4882678Z code: 422
2020-06-26T13:32:24.4883177Z OK: 'skuber.apps.v1.Deployment' labeled: 'app: redis, name: redis-slave, role: slave, tier: backend'
2020-06-26T13:32:24.4883773Z Error[422]: 'skuber.Service', details:
2020-06-26T13:32:24.4884063Z ---
2020-06-26T13:32:24.4884229Z apiVersion: "v1"
2020-06-26T13:32:24.4884408Z kind: "Status"
2020-06-26T13:32:24.4884571Z metadata: {}
2020-06-26T13:32:24.4885100Z status: "Failure"
2020-06-26T13:32:24.4885300Z message: "Service \"frontend\" is invalid: [metadata.resourceVersion: Invalid value:\
2020-06-26T13:32:24.4885545Z   \ \"\": must be specified for an update, spec.clusterIP: Invalid value: \"\": field\
2020-06-26T13:32:24.4885742Z   \ is immutable]"
2020-06-26T13:32:24.4886121Z reason: "Invalid"
2020-06-26T13:32:24.4886300Z details:
2020-06-26T13:32:24.4886460Z   name: "frontend"
2020-06-26T13:32:24.4886620Z   kind: "Service"
2020-06-26T13:32:24.4886776Z   causes:
2020-06-26T13:32:24.4887131Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4887326Z     message: "Invalid value: \"\": must be specified for an update"
2020-06-26T13:32:24.4887514Z     field: "metadata.resourceVersion"
2020-06-26T13:32:24.4887840Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4888036Z     message: "Invalid value: \"\": must be specified for an update"
2020-06-26T13:32:24.4888227Z     field: "metadata.resourceVersion"
2020-06-26T13:32:24.4888544Z   - reason: "FieldValueInvalid"
2020-06-26T13:32:24.4892178Z     message: "Invalid value: \"\": field is immutable"
2020-06-26T13:32:24.4894105Z     field: "spec.clusterIP"
2020-06-26T13:32:24.4894328Z code: 422
2020-06-26T13:32:24.4895000Z OK: 'skuber.apps.v1.Deployment' labeled: 'app: guestbook, name: frontend, tier: frontend'
2020-06-26T13:32:24.4895435Z OK: 'skuber.networking.NetworkPolicy' labeled: 'name: default-deny-all'
2020-06-26T13:32:24.4895815Z OK: 'skuber.networking.NetworkPolicy' labeled: 'name: external-frontend'
2020-06-26T13:32:24.4896226Z OK: 'skuber.networking.NetworkPolicy' labeled: 'app: guestbook, name: front-redis'
2020-06-26T13:32:24.4896633Z OK: 'skuber.networking.NetworkPolicy' labeled: 'app: guestbook, name: redis-master-slave'
2020-06-26T13:32:24.4897041Z OK: 'skuber.networking.NetworkPolicy' labeled: 'app: guestbook, name: redis-slave-master'
2020-06-26T13:32:24.4897552Z OK: 'skuber.networking.NetworkPolicy' labeled: 'name: front-k8s-dns'
2020-06-26T13:32:24.4898131Z OK: 'skuber.networking.NetworkPolicy' labeled: 'name: redis-slave-k8s-dns'
2020-06-26T13:32:24.4898359Z All done.
2020-06-26T13:32:24.4901940Z [ERROR] [06/26/2020 13:32:24.442] [a-system-akka.actor.default-dispatcher-6] [akka://a-system/system/pool-master] connection pool for PoolGateway(hcps = HostConnectionPoolSetup(35.242.192.128,443,ConnectionPoolSetup(ConnectionPoolSettings(4,0,5,32,1,Duration.Inf,100 milliseconds,2 minutes,30 seconds,ClientConnectionSettings(Some(User-Agent: akka-http/10.1.9),10 seconds,1 minute,512,None,WebSocketSettings(<function0>,ping,Duration.Inf,akka.http.impl.settings.WebSocketSettingsImpl$$$Lambda$219/363397863@393fc189),List(),ParserSettings(2048,16,64,64,8192,64,8388608,8388608,256,1048576,Strict,RFC6265,true,Set(),Full,Error,HashMap(If-Range -> 0, If-Modified-Since -> 0, If-Unmodified-Since -> 0, default -> 12, If-None-Match -> 0, User-Agent -> 32, Content-MD5 -> 0, Date -> 0, If-Match -> 0),false,true,akka.util.ConstantFun$$$Lambda$199/265348534@505948a0,akka.util.ConstantFun$$$Lambda$199/265348534@505948a0,akka.util.ConstantFun$$$Lambda$200/1324173038@5a48a293),None,TCPTransport),New,1 second),akka.http.scaladsl.HttpsConnectionContext@1dbc03da,akka.event.MarkerLoggingAdapter@1898f2a4))) has shut down unexpectedly
2020-06-26T13:32:24.4902996Z [ERROR] [06/26/2020 13:32:24.452] [a-system-akka.actor.default-dispatcher-17] [akka.actor.ActorSystemImpl(a-system)] Outgoing request stream error (akka.stream.AbruptTerminationException: Processor actor [Actor[akka://a-system/system/StreamSupervisor-1/flow-0-0-PoolFlow#-1257911594]] terminated abruptly)

Apply extra scalac options

Proposed compiler options from one of my past projects:

  val commonScalacOptions = Seq("-deprecation", "-feature", "-unchecked", "-Xfatal-warnings", "-Ybackend-parallelism", "8")
  val warnScalacOptions = {
    "dead-code extra-implicit inaccessible infer-any"
      .split(" ").map("-Ywarn-" + _)
  }
  val lintScalacOptions = {
    "doc-detached missing-interpolator nullary-override nullary-unit private-shadow stars-align type-parameter-shadow unsound-match"
      .split(" ").map("-Xlint:" + _)
  }
  // partial-unification and scalatest don't like each other, should use them only in prod.
  // At least until this is merged/new release is out: https://github.com/scalatest/scalatest/issues/1165
  val productionOnlyScalacOptions = Seq("-Ywarn-value-discard", "-Ypartial-unification")

  lazy val commonSettings = Seq(
    scalaVersion := "2.12.10",
    scalacOptions ++= commonScalacOptions ++ warnScalacOptions ++ lintScalacOptions,
    scalacOptions in Compile ++= productionOnlyScalacOptions,
......

-Ywarn-value-discard is probably the most important one, it makes spotting e.g. dangling Futures/IOs easier.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.