SlideShare a Scribd company logo
1 of 17
Download to read offline
Google Cloud Platform
How Does Kubernetes
Build OpenAPI Specifications?
Gluecon
2018-05-16
Daniel Smith <dbsmith@google.com>
Staff Software Engineer
originalavalamp@ (twitter)
(c) Google LLC
Kubernetes Resource Model in 60 seconds
● Allow humans and automated systems to work together
● Standardize all the things!
○ metadata
○ verbs
● Little control loops instead of big state machines
● JSON and proto transport mechanisms
● Clients generated from OpenAPI specs!
● And OpenAPI specs are generated from...
Our IDL. ish.
// Deployment enables declarative updates for Pods and ReplicaSets.
type Deployment struct {
metav1.TypeMeta `json:",inline"`
// Standard object metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Specification of the desired behavior of the Deployment.
// +optional
Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
// Most recently observed status of the Deployment.
// +optional
Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
Our IDL. ish.
// Deployment enables declarative updates for Pods and ReplicaSets.
type Deployment struct {
metav1.TypeMeta `json:",inline"`
// Standard object metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Specification of the desired behavior of the Deployment.
// +optional
Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
// Most recently observed status of the Deployment.
// +optional
Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
User-visible documentation
Instructions for OpenAPI generator
Compilable go code
Our IDL - Continued
// DeploymentSpec is the specification of the desired behavior of the Deployment.
type DeploymentSpec struct {
// Number of desired pods. This is a pointer to distinguish between explicit
// zero and not specified. Defaults to 1.
// +optional
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
// Template describes the pods that will be created.
Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"`
// Indicates that the deployment is paused.
// +optional
Paused bool `json:"paused,omitempty" protobuf:"varint,7,opt,name=paused"`
...
// The maximum time in seconds for a deployment to make progress before it
// is considered to be failed. The deployment controller will continue to
// process failed deployments and a condition with a ProgressDeadlineExceeded
// reason will be surfaced in the deployment status. Note that progress will
// not be estimated during the time a deployment is paused. Defaults to 600s.
ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty" protobuf:"varint,9,opt,name=progressDeadlineSeconds"`
}
...shouldn’t that be a proto file?
...shouldn’t that be a proto file?
● Maybe
(Phase 1) Compile step
● Repo: kubernetes/kube-openapi
● Uses a go parser / code generator library (“gengo”)
● Defines some extension tags...
// This is the comment tag that carries parameters for open API generation.
const tagName = "k8s:openapi-gen"
const tagOptional = "optional"
// Known values for the tag.
const (
tagExtensionPrefix = "x-kubernetes-"
tagPatchStrategy = "patchStrategy"
tagPatchMergeKey = "patchMergeKey"
patchStrategyExtensionName = "patch-strategy"
patchMergeKeyExtensionName = "patch-merge-key"
)
Output artifact: another go file
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
...
"k8s.io/api/apps/v1.Deployment": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "Deployment enables declarative updates for Pods and ReplicaSets.",
Properties: map[string]spec.Schema{
"kind": {
SchemaProps: spec.SchemaProps{
Description: "Kind is a string value ...",
Type: []string{"string"},
Format: "",
},
},
"apiVersion": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion defines the versioned schema ...",
Type: []string{"string"},
Format: "",
},
},
"metadata": {
SchemaProps: spec.SchemaProps{
Description: "Standard object metadata.",
Output artifact: another go file
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
...
"k8s.io/api/apps/v1.Deployment": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "Deployment enables declarative updates for Pods and ReplicaSets.",
Properties: map[string]spec.Schema{
"kind": {
SchemaProps: spec.SchemaProps{
Description: "Kind is a string value ...",
Type: []string{"string"},
Format: "",
},
},
"apiVersion": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion defines the versioned schema ...",
Type: []string{"string"},
Format: "",
},
},
"metadata": {
SchemaProps: spec.SchemaProps{
Description: "Standard object metadata.",
from: https://github.com/go-openapi/spec
// OpenAPIDefinition describes single type. Normally
these definitions are auto-generated using gen-openapi.
type OpenAPIDefinition struct {
Schema
spec.Schema
Dependencies []string
}
Output artifact: another go file
...
"k8s.io/apimachinery/pkg/util/intstr.IntOrString": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: intstr.IntOrString{}.OpenAPISchemaType(),
Format: intstr.IntOrString{}.OpenAPISchemaFormat(),
},
},
},
Define your own!
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ IntOrString) OpenAPISchemaType() []string { return []string{"string"} }
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ IntOrString) OpenAPISchemaFormat() string { return "int-or-string" }
Phase 2 (runtime): Time to add the verbs...
From here...
case "PUT": // Update a resource.
doc := "replace the specified " + kind
if isSubresource {
doc = "replace " + subresource + " of the specified " + kind
}
handler := metrics.InstrumentRouteFunc(action.Verb, resource, subresource, requestScope,
restfulUpdateResource(updater, reqScope, admit))
route := ws.PUT(action.Path).To(handler).
Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Operation("replace"+namespaced+kind+strings.Title(subresource)+operationSuffix).
Produces(append(storageMeta.ProducesMIMETypes(action.Verb), mediaTypes...)...).
Returns(http.StatusOK, "OK", producedObject).
// TODO: in some cases, the API may return a v1.Status instead of the versioned object
// but currently go-restful can't handle multiple different objects being returned.
Returns(http.StatusCreated, "Created", producedObject).
Reads(defaultVersionedObject).
Writes(producedObject)
addParams(route, action.Params)
routes = append(routes, route)
Phase 2 (runtime): Construct the spec
// BuildAndRegisterOpenAPIVersionedService builds the spec and registers a handler to provides access to it.
// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then
RegisterOpenAPIVersionedService.
func BuildAndRegisterOpenAPIVersionedService(servePath string, webServices []*restful.WebService, config *common.Config, handler
common.PathHandler) (*OpenAPIService, error) { ... }
// BuildOpenAPISpec builds OpenAPI spec given a list of webservices (containing routes) and common.Config to customize it.
func BuildOpenAPISpec(webServices []*restful.WebService, config *common.Config) (*spec.Swagger, error) {
o := openAPI{
config: config,
swagger: &spec.Swagger{
SwaggerProps: spec.SwaggerProps{
Swagger: OpenAPIVersion,
Definitions: spec.Definitions{},
Paths: &spec.Paths{Paths: map[string]spec.PathItem{}},
Info: config.Info,
},
},
}
err := o.init(webServices)
if err != nil {
return nil, err
}
return o.swagger, nil
}
Phase 2.5: Aggregation
// MergeSpecs copies paths and definitions from source to dest, rename definitions if needed.
// dest will be mutated, and source will not be changed. It will fail on path conflicts.
func MergeSpecs(dest, source *spec.Swagger) error {
return mergeSpecs(dest, source, true, false)
}
// MergeSpecsIgnorePathConflict is the same as MergeSpecs except it will ignore any path
// conflicts by keeping the paths of destination. It will rename definition conflicts.
func MergeSpecsIgnorePathConflict(dest, source *spec.Swagger) error {
return mergeSpecs(dest, source, true, true)
}
// FilterSpecByPaths removes unnecessary paths and definitions used by those paths.
// i.e. if a Path removed by this function, all definition used by it and not used
// anywhere else will also be removed.
func FilterSpecByPaths(sp *spec.Swagger, keepPathPrefixes []string) {
...
}
Phase 3: Client usage
● The spec can change on the fly, so use ETAGs
● kubectl (our CLI) caches discovery information
● It is big, so compress
● It is slow to unmarshal JSON, so use proto
○ We reused the proto format from gnostic
● Many versions
○ OpenAPI version
○ proto encoding version
○ Our API version
Future work ideas
● Declare as much as possible in our IDL
○ Validation
○ Defaults
○ Const/immutability marker
○ Which of the standard verbs we support?
○ Subresources?
● OpenAPI -> protobuf definition?
○ `x-proto-tag` extension? (From openapi2proto)
● Custom extension tags
○ We’re moving `kubectl apply` (schema-aware smart update feature) to the control plane
○ (this could be a large rabbit hole)
Google Cloud Platform
Thank you!
Sound interesting? We’re hiring...
(c) Google LLC

More Related Content

What's hot

Running Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming ApplicationsRunning Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming ApplicationsLightbend
 
Receive side scaling (RSS) with eBPF in QEMU and virtio-net
Receive side scaling (RSS) with eBPF in QEMU and virtio-netReceive side scaling (RSS) with eBPF in QEMU and virtio-net
Receive side scaling (RSS) with eBPF in QEMU and virtio-netYan Vugenfirer
 
Kubernetes Probes (Liveness, Readyness, Startup) Introduction
Kubernetes Probes (Liveness, Readyness, Startup) IntroductionKubernetes Probes (Liveness, Readyness, Startup) Introduction
Kubernetes Probes (Liveness, Readyness, Startup) IntroductionAkhmadZakiAlsafi
 
Monitoring Flink with Prometheus
Monitoring Flink with PrometheusMonitoring Flink with Prometheus
Monitoring Flink with PrometheusMaximilian Bode
 
Hearts Of Darkness - a Spring DevOps Apocalypse
Hearts Of Darkness - a Spring DevOps ApocalypseHearts Of Darkness - a Spring DevOps Apocalypse
Hearts Of Darkness - a Spring DevOps ApocalypseJoris Kuipers
 
Schemas Beyond The Edge
Schemas Beyond The EdgeSchemas Beyond The Edge
Schemas Beyond The Edgeconfluent
 
ACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introduction
ACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introductionACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introduction
ACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introductionProject ACRN
 
Linux Networking Explained
Linux Networking ExplainedLinux Networking Explained
Linux Networking ExplainedThomas Graf
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebBryan Helmig
 
Europycon2011: Implementing distributed application using ZeroMQ
Europycon2011: Implementing distributed application using ZeroMQEuropycon2011: Implementing distributed application using ZeroMQ
Europycon2011: Implementing distributed application using ZeroMQfcrippa
 
Building Real-Time Travel Alerts
Building Real-Time Travel AlertsBuilding Real-Time Travel Alerts
Building Real-Time Travel AlertsTimothy Spann
 
Advanced Captive Portal - pfSense Hangout June 2017
Advanced Captive Portal - pfSense Hangout June 2017Advanced Captive Portal - pfSense Hangout June 2017
Advanced Captive Portal - pfSense Hangout June 2017Netgate
 
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...HostedbyConfluent
 

What's hot (20)

GRPC.pptx
GRPC.pptxGRPC.pptx
GRPC.pptx
 
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming ApplicationsRunning Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
 
Receive side scaling (RSS) with eBPF in QEMU and virtio-net
Receive side scaling (RSS) with eBPF in QEMU and virtio-netReceive side scaling (RSS) with eBPF in QEMU and virtio-net
Receive side scaling (RSS) with eBPF in QEMU and virtio-net
 
Kubernetes Probes (Liveness, Readyness, Startup) Introduction
Kubernetes Probes (Liveness, Readyness, Startup) IntroductionKubernetes Probes (Liveness, Readyness, Startup) Introduction
Kubernetes Probes (Liveness, Readyness, Startup) Introduction
 
Monitoring Flink with Prometheus
Monitoring Flink with PrometheusMonitoring Flink with Prometheus
Monitoring Flink with Prometheus
 
Rate limits and all about
Rate limits and all aboutRate limits and all about
Rate limits and all about
 
Hearts Of Darkness - a Spring DevOps Apocalypse
Hearts Of Darkness - a Spring DevOps ApocalypseHearts Of Darkness - a Spring DevOps Apocalypse
Hearts Of Darkness - a Spring DevOps Apocalypse
 
Schemas Beyond The Edge
Schemas Beyond The EdgeSchemas Beyond The Edge
Schemas Beyond The Edge
 
AWS icons.pptx
AWS icons.pptxAWS icons.pptx
AWS icons.pptx
 
ACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introduction
ACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introductionACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introduction
ACRN vMeet-Up EU 2021 - shared memory based inter-vm communication introduction
 
Linux Networking Explained
Linux Networking ExplainedLinux Networking Explained
Linux Networking Explained
 
hpsr-2020-srv6-tutorial
hpsr-2020-srv6-tutorialhpsr-2020-srv6-tutorial
hpsr-2020-srv6-tutorial
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWeb
 
GTPing, How To
GTPing, How ToGTPing, How To
GTPing, How To
 
Europycon2011: Implementing distributed application using ZeroMQ
Europycon2011: Implementing distributed application using ZeroMQEuropycon2011: Implementing distributed application using ZeroMQ
Europycon2011: Implementing distributed application using ZeroMQ
 
Building Real-Time Travel Alerts
Building Real-Time Travel AlertsBuilding Real-Time Travel Alerts
Building Real-Time Travel Alerts
 
Spring GraphQL
Spring GraphQLSpring GraphQL
Spring GraphQL
 
Advanced Captive Portal - pfSense Hangout June 2017
Advanced Captive Portal - pfSense Hangout June 2017Advanced Captive Portal - pfSense Hangout June 2017
Advanced Captive Portal - pfSense Hangout June 2017
 
Using mikrotik with radius
Using mikrotik with radiusUsing mikrotik with radius
Using mikrotik with radius
 
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
 

Similar to How Does Kubernetes Build OpenAPI Specifications?

OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneidermfrancis
 
Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017Arnaud Giuliani
 
Introduction to Apache Mesos
Introduction to Apache MesosIntroduction to Apache Mesos
Introduction to Apache MesosJoe Stein
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Node.js basics
Node.js basicsNode.js basics
Node.js basicsBen Lin
 
Java design patterns
Java design patternsJava design patterns
Java design patternsShawn Brito
 
Angular 1.6 typescript application
Angular 1.6 typescript applicationAngular 1.6 typescript application
Angular 1.6 typescript applicationYitzchak Meirovich
 
Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)DECK36
 
Php 5.6 From the Inside Out
Php 5.6 From the Inside OutPhp 5.6 From the Inside Out
Php 5.6 From the Inside OutFerenc Kovács
 
Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Sylvain Wallez
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.jsdavidchubbs
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGuillaume Laforge
 
Orchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and MspectatorOrchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and MspectatorRaphaël PINSON
 
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Puppet
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleSkills Matter
 
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...Igalia
 

Similar to How Does Kubernetes Build OpenAPI Specifications? (20)

OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneider
 
Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017Develop your next app with kotlin @ AndroidMakersFr 2017
Develop your next app with kotlin @ AndroidMakersFr 2017
 
Introduction to Apache Mesos
Introduction to Apache MesosIntroduction to Apache Mesos
Introduction to Apache Mesos
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Node.js basics
Node.js basicsNode.js basics
Node.js basics
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
 
Angular 1.6 typescript application
Angular 1.6 typescript applicationAngular 1.6 typescript application
Angular 1.6 typescript application
 
Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)
 
Php 5.6 From the Inside Out
Php 5.6 From the Inside OutPhp 5.6 From the Inside Out
Php 5.6 From the Inside Out
 
Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!
 
Amazon elastic map reduce
Amazon elastic map reduceAmazon elastic map reduce
Amazon elastic map reduce
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.js
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
 
Orchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and MspectatorOrchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and Mspectator
 
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
Orchestrated Functional Testing with Puppet-spec and Mspectator - PuppetConf ...
 
Spock
SpockSpock
Spock
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
 
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
 

Recently uploaded

[GRCPP] Introduction to concepts (C++20)
[GRCPP] Introduction to concepts (C++20)[GRCPP] Introduction to concepts (C++20)
[GRCPP] Introduction to concepts (C++20)Dimitrios Platis
 
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfryanfarris8
 
Software Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements EngineeringSoftware Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements EngineeringPrakhyath Rai
 
The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)Roberto Bettazzoni
 
Novo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNovo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNeo4j
 
Your Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | EvmuxYour Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | Evmuxevmux96
 
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
Workshop -  Architecting Innovative Graph Applications- GraphSummit MilanWorkshop -  Architecting Innovative Graph Applications- GraphSummit Milan
Workshop - Architecting Innovative Graph Applications- GraphSummit MilanNeo4j
 
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Flutter Agency
 
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Lisi Hocke
 
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...Abortion Clinic
 
Rapidoform for Modern Form Building and Insights
Rapidoform for Modern Form Building and InsightsRapidoform for Modern Form Building and Insights
Rapidoform for Modern Form Building and Insightsrapidoform
 
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanWorkshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanNeo4j
 
Effective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConEffective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConNatan Silnitsky
 
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jGraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jNeo4j
 

Recently uploaded (20)

[GRCPP] Introduction to concepts (C++20)
[GRCPP] Introduction to concepts (C++20)[GRCPP] Introduction to concepts (C++20)
[GRCPP] Introduction to concepts (C++20)
 
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
 
Software Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements EngineeringSoftware Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements Engineering
 
The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)
 
Novo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNovo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMs
 
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
 
Your Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | EvmuxYour Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | Evmux
 
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
Workshop -  Architecting Innovative Graph Applications- GraphSummit MilanWorkshop -  Architecting Innovative Graph Applications- GraphSummit Milan
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
 
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
 
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
 
Abortion Pill Prices Jozini ](+27832195400*)[ 🏥 Women's Abortion Clinic in Jo...
Abortion Pill Prices Jozini ](+27832195400*)[ 🏥 Women's Abortion Clinic in Jo...Abortion Pill Prices Jozini ](+27832195400*)[ 🏥 Women's Abortion Clinic in Jo...
Abortion Pill Prices Jozini ](+27832195400*)[ 🏥 Women's Abortion Clinic in Jo...
 
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
 
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
 
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
 
Rapidoform for Modern Form Building and Insights
Rapidoform for Modern Form Building and InsightsRapidoform for Modern Form Building and Insights
Rapidoform for Modern Form Building and Insights
 
Abortion Clinic In Stanger ](+27832195400*)[ 🏥 Safe Abortion Pills In Stanger...
Abortion Clinic In Stanger ](+27832195400*)[ 🏥 Safe Abortion Pills In Stanger...Abortion Clinic In Stanger ](+27832195400*)[ 🏥 Safe Abortion Pills In Stanger...
Abortion Clinic In Stanger ](+27832195400*)[ 🏥 Safe Abortion Pills In Stanger...
 
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanWorkshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
 
Effective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConEffective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeCon
 
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jGraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
 
Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...
 

How Does Kubernetes Build OpenAPI Specifications?

  • 1. Google Cloud Platform How Does Kubernetes Build OpenAPI Specifications? Gluecon 2018-05-16 Daniel Smith <dbsmith@google.com> Staff Software Engineer originalavalamp@ (twitter) (c) Google LLC
  • 2. Kubernetes Resource Model in 60 seconds ● Allow humans and automated systems to work together ● Standardize all the things! ○ metadata ○ verbs ● Little control loops instead of big state machines ● JSON and proto transport mechanisms ● Clients generated from OpenAPI specs! ● And OpenAPI specs are generated from...
  • 3. Our IDL. ish. // Deployment enables declarative updates for Pods and ReplicaSets. type Deployment struct { metav1.TypeMeta `json:",inline"` // Standard object metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Specification of the desired behavior of the Deployment. // +optional Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // Most recently observed status of the Deployment. // +optional Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` }
  • 4. Our IDL. ish. // Deployment enables declarative updates for Pods and ReplicaSets. type Deployment struct { metav1.TypeMeta `json:",inline"` // Standard object metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Specification of the desired behavior of the Deployment. // +optional Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // Most recently observed status of the Deployment. // +optional Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } User-visible documentation Instructions for OpenAPI generator Compilable go code
  • 5. Our IDL - Continued // DeploymentSpec is the specification of the desired behavior of the Deployment. type DeploymentSpec struct { // Number of desired pods. This is a pointer to distinguish between explicit // zero and not specified. Defaults to 1. // +optional Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` // Template describes the pods that will be created. Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // Indicates that the deployment is paused. // +optional Paused bool `json:"paused,omitempty" protobuf:"varint,7,opt,name=paused"` ... // The maximum time in seconds for a deployment to make progress before it // is considered to be failed. The deployment controller will continue to // process failed deployments and a condition with a ProgressDeadlineExceeded // reason will be surfaced in the deployment status. Note that progress will // not be estimated during the time a deployment is paused. Defaults to 600s. ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty" protobuf:"varint,9,opt,name=progressDeadlineSeconds"` }
  • 6. ...shouldn’t that be a proto file?
  • 7. ...shouldn’t that be a proto file? ● Maybe
  • 8. (Phase 1) Compile step ● Repo: kubernetes/kube-openapi ● Uses a go parser / code generator library (“gengo”) ● Defines some extension tags... // This is the comment tag that carries parameters for open API generation. const tagName = "k8s:openapi-gen" const tagOptional = "optional" // Known values for the tag. const ( tagExtensionPrefix = "x-kubernetes-" tagPatchStrategy = "patchStrategy" tagPatchMergeKey = "patchMergeKey" patchStrategyExtensionName = "patch-strategy" patchMergeKeyExtensionName = "patch-merge-key" )
  • 9. Output artifact: another go file func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ ... "k8s.io/api/apps/v1.Deployment": { Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ Description: "Deployment enables declarative updates for Pods and ReplicaSets.", Properties: map[string]spec.Schema{ "kind": { SchemaProps: spec.SchemaProps{ Description: "Kind is a string value ...", Type: []string{"string"}, Format: "", }, }, "apiVersion": { SchemaProps: spec.SchemaProps{ Description: "APIVersion defines the versioned schema ...", Type: []string{"string"}, Format: "", }, }, "metadata": { SchemaProps: spec.SchemaProps{ Description: "Standard object metadata.",
  • 10. Output artifact: another go file func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ ... "k8s.io/api/apps/v1.Deployment": { Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ Description: "Deployment enables declarative updates for Pods and ReplicaSets.", Properties: map[string]spec.Schema{ "kind": { SchemaProps: spec.SchemaProps{ Description: "Kind is a string value ...", Type: []string{"string"}, Format: "", }, }, "apiVersion": { SchemaProps: spec.SchemaProps{ Description: "APIVersion defines the versioned schema ...", Type: []string{"string"}, Format: "", }, }, "metadata": { SchemaProps: spec.SchemaProps{ Description: "Standard object metadata.", from: https://github.com/go-openapi/spec // OpenAPIDefinition describes single type. Normally these definitions are auto-generated using gen-openapi. type OpenAPIDefinition struct { Schema spec.Schema Dependencies []string }
  • 11. Output artifact: another go file ... "k8s.io/apimachinery/pkg/util/intstr.IntOrString": { Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ Type: intstr.IntOrString{}.OpenAPISchemaType(), Format: intstr.IntOrString{}.OpenAPISchemaFormat(), }, }, }, Define your own! // OpenAPISchemaType is used by the kube-openapi generator when constructing // the OpenAPI spec of this type. // // See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators func (_ IntOrString) OpenAPISchemaType() []string { return []string{"string"} } // OpenAPISchemaFormat is used by the kube-openapi generator when constructing // the OpenAPI spec of this type. func (_ IntOrString) OpenAPISchemaFormat() string { return "int-or-string" }
  • 12. Phase 2 (runtime): Time to add the verbs... From here... case "PUT": // Update a resource. doc := "replace the specified " + kind if isSubresource { doc = "replace " + subresource + " of the specified " + kind } handler := metrics.InstrumentRouteFunc(action.Verb, resource, subresource, requestScope, restfulUpdateResource(updater, reqScope, admit)) route := ws.PUT(action.Path).To(handler). Doc(doc). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Operation("replace"+namespaced+kind+strings.Title(subresource)+operationSuffix). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), mediaTypes...)...). Returns(http.StatusOK, "OK", producedObject). // TODO: in some cases, the API may return a v1.Status instead of the versioned object // but currently go-restful can't handle multiple different objects being returned. Returns(http.StatusCreated, "Created", producedObject). Reads(defaultVersionedObject). Writes(producedObject) addParams(route, action.Params) routes = append(routes, route)
  • 13. Phase 2 (runtime): Construct the spec // BuildAndRegisterOpenAPIVersionedService builds the spec and registers a handler to provides access to it. // Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIVersionedService. func BuildAndRegisterOpenAPIVersionedService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) { ... } // BuildOpenAPISpec builds OpenAPI spec given a list of webservices (containing routes) and common.Config to customize it. func BuildOpenAPISpec(webServices []*restful.WebService, config *common.Config) (*spec.Swagger, error) { o := openAPI{ config: config, swagger: &spec.Swagger{ SwaggerProps: spec.SwaggerProps{ Swagger: OpenAPIVersion, Definitions: spec.Definitions{}, Paths: &spec.Paths{Paths: map[string]spec.PathItem{}}, Info: config.Info, }, }, } err := o.init(webServices) if err != nil { return nil, err } return o.swagger, nil }
  • 14. Phase 2.5: Aggregation // MergeSpecs copies paths and definitions from source to dest, rename definitions if needed. // dest will be mutated, and source will not be changed. It will fail on path conflicts. func MergeSpecs(dest, source *spec.Swagger) error { return mergeSpecs(dest, source, true, false) } // MergeSpecsIgnorePathConflict is the same as MergeSpecs except it will ignore any path // conflicts by keeping the paths of destination. It will rename definition conflicts. func MergeSpecsIgnorePathConflict(dest, source *spec.Swagger) error { return mergeSpecs(dest, source, true, true) } // FilterSpecByPaths removes unnecessary paths and definitions used by those paths. // i.e. if a Path removed by this function, all definition used by it and not used // anywhere else will also be removed. func FilterSpecByPaths(sp *spec.Swagger, keepPathPrefixes []string) { ... }
  • 15. Phase 3: Client usage ● The spec can change on the fly, so use ETAGs ● kubectl (our CLI) caches discovery information ● It is big, so compress ● It is slow to unmarshal JSON, so use proto ○ We reused the proto format from gnostic ● Many versions ○ OpenAPI version ○ proto encoding version ○ Our API version
  • 16. Future work ideas ● Declare as much as possible in our IDL ○ Validation ○ Defaults ○ Const/immutability marker ○ Which of the standard verbs we support? ○ Subresources? ● OpenAPI -> protobuf definition? ○ `x-proto-tag` extension? (From openapi2proto) ● Custom extension tags ○ We’re moving `kubectl apply` (schema-aware smart update feature) to the control plane ○ (this could be a large rabbit hole)
  • 17. Google Cloud Platform Thank you! Sound interesting? We’re hiring... (c) Google LLC