Thanks to visit codestin.com
Credit goes to github.com

Skip to content
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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Dtab
</h4>
<div id="dtab"></div>
<div class="namerd-dtab-warning hide">Note: the above Dentries are from namerd and can't be edited.</div>
<div class="namerd-dtab-warning hide">Note: the above Dentries are from an external source and can't be edited.</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, this has been bothering me

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I think you'll need to recompile the templates in order for this change to take effect)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I realized that: d215b98 :)

<div id="dtab-base"></div>

<div id="dtab-edit" class="hide">
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
io.buoyant.interpreter.k8s.ConfigMapInterpreterInitializer
io.buoyant.interpreter.k8s.IstioInterpreterInitializer
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package io.buoyant.interpreter
package k8s

import com.fasterxml.jackson.annotation.JsonIgnore
import com.twitter.finagle.Dtab
import com.twitter.finagle.Stack.Params
import com.twitter.finagle.naming.NameInterpreter
import com.twitter.finagle.param.Label
import com.twitter.logging.Logger
import com.twitter.util._
import io.buoyant.config.types.Port
import io.buoyant.k8s.ClientConfig
import io.buoyant.k8s.v1._
import io.buoyant.namer.{ConfiguredDtabNamer, InterpreterConfig, InterpreterInitializer, Param}
import java.util.concurrent.atomic.AtomicReference

class ConfigMapInterpreterInitializer extends InterpreterInitializer {
val configClass = classOf[ConfigMapInterpreterConfig]
override def configId: String = "io.l5d.k8s.configMap"
}

object ConfigMapInterpreterInitializer extends ConfigMapInterpreterInitializer

case class ConfigMapInterpreterConfig(
host: Option[String],
port: Option[Port],
namespace: Option[String],
name: String,
filename: String
) extends InterpreterConfig with ClientConfig {
require(name != null, "ConfigMap name is required!")
require(filename != null, "ConfigMap dtab filename is required!")

@JsonIgnore
override def experimentalRequired = true

@JsonIgnore
def portNum = port.map(_.port)

@JsonIgnore
private[this] val log = Logger()

@JsonIgnore
val api = {
val client = mkClient(Params.empty).configured(Label("configMapInterpreter"))
val nsOrDefault = namespace.getOrElse(DefaultNamespace)
Api(client.newService(dst)).withNamespace(nsOrDefault)
}

@JsonIgnore
val act = api.configMap(name)
.activity(extractDtab) {
(dtab, event) =>
event match {
case ConfigMapAdded(a) => getDtab(a)
case ConfigMapModified(m) => getDtab(m)
case ConfigMapDeleted(_) =>
log.warning(s"k8s ConfigMap $name was deleted!")
Dtab.empty
case ConfigMapError(e) =>
log.error("k8s watch error: %s", e)
dtab
}
}

@JsonIgnore
@inline
private[this] def extractDtab(response: Option[ConfigMap]): Dtab =
response.map(getDtab).getOrElse {
log.warning(s"K8s ConfigMap %s doesn't exist, assuming it will be created", name)
Dtab.empty
}

@JsonIgnore
def getDtab(configMap: ConfigMap): Dtab =
configMap.data.get(filename) match {
case None =>
log.warning(s"dtab at %s in k8s ConfigMap %s did not exist!", filename, name)
Dtab.empty
case Some(data) => Dtab.read(data)
}

@JsonIgnore
override def newInterpreter(params: Params): NameInterpreter = {
val Param.Namers(namers) = params[Param.Namers]
ConfiguredDtabNamer(act, namers)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.buoyant.interpreter.k8s

import com.twitter.finagle.Dtab
import com.twitter.finagle.util.LoadService
import io.buoyant.config.Parser
import io.buoyant.config.types.Port
import io.buoyant.k8s.v1.ConfigMap
import io.buoyant.namer.{InterpreterConfig, InterpreterInitializer}
import io.buoyant.test.FunSuite
import org.scalatest.{Inside, OptionValues}

class ConfigMapInterpreterTest extends FunSuite
with Inside {

test("interpreter registration") {
assert(LoadService[InterpreterInitializer]()
.exists(_.isInstanceOf[ConfigMapInterpreterInitializer]))
}

private[this] def parse(yaml: String): ConfigMapInterpreterConfig = Parser.objectMapper(yaml, Iterable(Seq(ConfigMapInterpreterInitializer)))
.readValue[InterpreterConfig](yaml)
.asInstanceOf[ConfigMapInterpreterConfig]

test("parse config") {
val yaml =
s"""|kind: io.l5d.k8s.configMap
|host: "foo"
|port: 8888
|namespace: "my-great-namespace"
|name: "configMap"
|filename: "test.dtab"
|""".stripMargin
val config = parse(yaml)
inside(config) {
case ConfigMapInterpreterConfig(host, port, namespace, name, filename) =>
assert(host.contains("foo"))
assert(port.contains(Port(8888)))
assert(namespace.contains("my-great-namespace"))
assert(name == "configMap")
assert(filename == "test.dtab")
}
}

test("get empty dtab") {
val yaml =
s"""|kind: io.l5d.k8s.configMap
|name: "configMap"
|filename: "test.dtab"
|""".stripMargin
val config = parse(yaml)
val configMap = ConfigMap(Map[String, String]())
assert(config.getDtab(configMap).isEmpty)
}

test("get non-empty dtab") {
val yaml =
s"""|kind: io.l5d.k8s.configMap
|name: "configMap"
|filename: "test.dtab"
|""".stripMargin
val config = parse(yaml)
val dtab = "/foo => /bar/baz;"
val configMap = ConfigMap(Map(
"test.dtab" -> dtab,
"otherTest.dtab" -> "quux => quuux"
))
assert(config.getDtab(configMap) == Dtab.read(dtab))
}
}
21 changes: 15 additions & 6 deletions k8s/src/main/scala/io/buoyant/k8s/Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,32 @@ trait ObjectDescriptor[O <: KubeObject, W <: Watch[O]] {
* Describes an Object in the Kubernetes API (i.e.
* http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_endpoints)
*/
trait KubeObject {
trait KubeObject extends KubeMetadata {
def apiVersion: Option[String]
def metadata: Option[ObjectMeta]
def kind: Option[String]
}

/**
* A Kubernetes API response with a `metadata` field.
*
* This is factored out from [[KubeObject]] and [[KubeList]] so that
* the `G` type param on [[Watchable]] can be constrained based on it,
* while still allowing both [[KubeObject]]s and [[KubeList]]s to be
* [[Watchable]], *and* maintaining the distinction between objects
* and lists.
*/
trait KubeMetadata {
def metadata: Option[ObjectMeta]
}

/**
* Describes a List of Objects in the Kubernetes API (i.e.
* [[http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_endpointslist EndpointsList]])
*
* @tparam O the type of object contained in the list
*/
trait KubeList[O <: KubeObject] {
trait KubeList[O <: KubeObject] extends KubeMetadata {
def items: Seq[O]
def apiVersion: Option[String]
def metadata: Option[ObjectMeta]
def kind: Option[String]
}

/**
Expand Down
Loading