From 578c5d06ca903f36763ae763f89050baa55278a4 Mon Sep 17 00:00:00 2001 From: Zack Date: Wed, 5 Apr 2017 15:42:21 -0700 Subject: [PATCH 1/6] Introduce a concept guide covering writing JSON and YAML based on a protobuf schema. --- _includes/doc-side-concepts-nav.html | 1 + docs/concepts/writing-config.md | 433 +++++++++++++++++++++++++++ 2 files changed, 434 insertions(+) create mode 100644 docs/concepts/writing-config.md diff --git a/_includes/doc-side-concepts-nav.html b/_includes/doc-side-concepts-nav.html index 0e31f91c72..d1f543cc9c 100644 --- a/_includes/doc-side-concepts-nav.html +++ b/_includes/doc-side-concepts-nav.html @@ -6,4 +6,5 @@
  • Attributes
  • Mixer
  • Configuration
  • +
  • Writing Configuration
  • diff --git a/docs/concepts/writing-config.md b/docs/concepts/writing-config.md new file mode 100644 index 0000000000..bf8ab611a2 --- /dev/null +++ b/docs/concepts/writing-config.md @@ -0,0 +1,433 @@ +--- +title: Writing Istio Configuration +headline: Writing Istio Configuration +sidenav: doc-side-concepts-nav.html +bodyclass: docs +layout: docs +type: markdown +--- + +{% capture overview %} +This document describes how to write configuration that conforms to Istio's schemas. All configuration schemas in Istio are defined as protobuf messages. When in doubt, search for the protos. +{% endcapture %} + +{% capture body %} +## Translating to JSON +The protobuf language guide defines [the canonical mapping between protobuf and JSON](https://developers.google.com/protocol-buffers/docs/proto3#json), refer to it as the source of truth. We provide a few specific examples that appear in the Mixer's configuration. + +### Proto `map`s and `message`s map to JSON objects: + + + + + + + + + + + + +
    ProtoJSON
    +
    +message Metric {
    +        string descriptor_name = 1;
    +        string value = 2;
    +        map labels = 3;
    +}
    +
    +
    +
    +{
    +  "descriptor_name": "request_count",
    +  "value": "1",
    +  "labels": {
    +      "source": "origin.ip",
    +        "target": "target.service",
    +  },
    +}  
    +
    +
    + +*Note that a map's keys are always converted to strings, no matter the data type declared in the proto file. They are converted back to the correct runtime type by the proto parsing libraries.* + +### A `repeated` Proto field maps to a JSON array: + + + + + + + + + + + + +
    ProtoJSON
    +
    +message Metric {
    +        string descriptor_name = 1;
    +        string value = 2;
    +        map labels = 3;
    +}
    +
    +message MetricsParams {
    +    repeated Metric metrics = 1;
    +}
    +
    +
    +
    +{
    +  "metrics": [
    +    {
    +      "descriptor_name": "request_count",
    +      "value": "1",
    +      "labels": {
    +            "source": "origin.ip",
    +            "target": "target.service",
    +      },
    +    }, {
    +      "descriptor_name": "request_latency",
    +      "value": "response.duration",
    +      "labels": {
    +            "source": "origin.ip",
    +            "target": "target.service",
    +      },
    +    }
    +  ]
    +}  
    +
    +
    + +*Note that we never name the outer-most message (the `MetricsParams`), but we do need the outer set of braces marking our JSON as an object.* + +### A proto `enum` field uses the name of the value you want to specify: + + + + + + + + + + + + +
    ProtoJSON
    +
    +enum ValueType {
    +    STRING = 1;
    +    INT64 = 2;
    +    DOUBLE = 3;
    +    // more values omitted
    +}
    +
    +message AttributeDescriptor {
    +    string name = 1;
    +    string description = 2;
    +    ValueType value_type = 3;
    +}
    +
    +
    +
    +{
    +  "name": "request.duration",
    +  "value_type": "INT64",
    +}
    +
    +
    + +*Notice we don't provide a `description`: fields with no value can be omitted.* + +### `message` fields can contain other messages: + + + + + + + + + + + +
    ProtoJSON
    +
    +enum ValueType {
    +    STRING = 1;
    +    INT64 = 2;
    +    DOUBLE = 3;
    +    // more values omitted
    +}
    +
    +message LabelDescriptor {
    +    string name = 1;
    +    string description = 2;
    +    ValueType value_type = 3;
    +}
    +
    +message MonitoredResourceDescriptor {
    +  string name = 1;
    +  string description = 2;
    +  repeated LabelDescriptor labels = 3;
    +}
    +
    +
    +
    +{
    +  "name": "My Monitored Resource",
    +  "labels": [
    +    {
    +      "name": "label one",
    +      "value_type": "STRING",
    +    }, {
    +      "name": "second label",
    +      "value_type": "DOUBLE",
    +    },
    +  ],
    +}
    +
    +
    + + +## Translating to YAML + +There is no canonical mapping between protobufs and YAML; instead protobuf defines a canonical mapping to JSON, and YAML defines a canonical mapping to JSON. To ingest YAML as a proto we convert it to JSON then to protobuf. + +**Important things to note:** +- YAML fields are implicitly strings +- JSON arrays map to YAML lists; each element in a list is prefixed by a dash (`-`) +- JSON objects map to a set of field names all at the same indentation level in YAML +- YAML is whitespace sensitive and must use spaces; tabs are never allowed + +### `map`s and `message`s: + + + + + + + + + + + + + +
    ProtoJSONYAML
    +
    +message Metric {
    +        string descriptor_name = 1;
    +        string value = 2;
    +        map labels = 3;
    +}
    +
    +
    +
    +{
    +  "descriptor_name": "request_count",
    +  "value": "1",
    +  "labels": {
    +      "source": "origin.ip",
    +        "target": "target.service",
    +  },
    +}  
    +
    +
    +
    +descriptor_name: request_count
    +value: "1"
    +labels:
    +  source: origin.ip
    +  target: target.service
    +
    +
    + +*Note that when numeric literals are used as strings (like `value` above) they must be enclosed in quotes. Quotation marks (`"`) are optional for normal strings.* + +### `repeated` fields: + + + + + + + + + + + + + +
    ProtoJSONYAML
    +
    +message Metric {
    +        string descriptor_name = 1;
    +        string value = 2;
    +        map labels = 3;
    +}
    +
    +message MetricsParams {
    +    repeated Metric metrics = 1;
    +}
    +
    +
    +
    +{
    +  "metrics": [
    +    {
    +      "descriptor_name": "request_count",
    +      "value": "1",
    +      "labels": {
    +            "source": "origin.ip",
    +            "target": "target.service",
    +      },
    +    }, {
    +      "descriptor_name": "request_latency",
    +      "value": "response.duration",
    +      "labels": {
    +            "source": "origin.ip",
    +            "target": "target.service",
    +      },
    +    }
    +  ]
    +}  
    +
    +
    +
    +metrics:
    +- descriptor_name: request_count
    +  value: "1"
    +  labels:
    +    source: origin.ip
    +    target: target.service
    +- descriptor_name: request_latency
    +  value: response.duration
    +  labels:
    +    source: origin.ip
    +    target: target.service
    +
    +
    + +### `enum` fields: + + + + + + + + + + + + + +
    ProtoJSONYAML
    +
    +enum ValueType {
    +    STRING = 1;
    +    INT64 = 2;
    +    DOUBLE = 3;
    +    // more values omitted
    +}
    +
    +message AttributeDescriptor {
    +    string name = 1;
    +    string description = 2;
    +    ValueType value_type = 3;
    +}
    +
    +
    +
    +{
    +  "name": "request.duration",
    +  "value_type": "INT64",
    +}
    +
    +
    +
    +name: request.duration
    +value_type: INT64
    +
    + +or + +
    +name: request.duration
    +valueType: INT64
    +
    +
    + +*Note that YAML parsing will handle both `snake_case` and `camelCase` field names.* + +### Nested `message`s: + + + + + + + + + + + + + +
    ProtoJSONYAML
    +
    +enum ValueType {
    +    STRING = 1;
    +    INT64 = 2;
    +    DOUBLE = 3;
    +    // more values omitted
    +}
    +
    +message LabelDescriptor {
    +    string name = 1;
    +    string description = 2;
    +    ValueType value_type = 3;
    +}
    +
    +message MonitoredResourceDescriptor {
    +  string name = 1;
    +  string description = 2;
    +  repeated LabelDescriptor labels = 3;
    +}
    +
    +
    +
    +{
    +  "name": "My Monitored Resource",
    +  "labels": [
    +    {
    +      "name": "label one",
    +      "value_type": "STRING",
    +    }, {
    +      "name": "second label",
    +      "value_type": "DOUBLE",
    +    },
    +  ],
    +}
    +
    +
    +
    +name: My Monitored Resource
    +labels:
    +- name: label one
    +  value_type: STRING
    +- name: second label
    +  value_type: DOUBLE
    +
    +
    + +{% endcapture %} + +{% capture whatsnext %} +* TODO: link to overall mixer config concept guide (how the config pieces fit together) +{% endcapture %} + +{% include templates/concept.md %} \ No newline at end of file From b0b7a50747e60102867136c2b5f81cb6bd3fe142 Mon Sep 17 00:00:00 2001 From: Zack Date: Mon, 10 Apr 2017 15:52:54 -0700 Subject: [PATCH 2/6] Update the section names so they're consistent and easier to read. --- docs/concepts/writing-config.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/concepts/writing-config.md b/docs/concepts/writing-config.md index bf8ab611a2..4439a7afb9 100644 --- a/docs/concepts/writing-config.md +++ b/docs/concepts/writing-config.md @@ -15,7 +15,7 @@ This document describes how to write configuration that conforms to Istio's sche ## Translating to JSON The protobuf language guide defines [the canonical mapping between protobuf and JSON](https://developers.google.com/protocol-buffers/docs/proto3#json), refer to it as the source of truth. We provide a few specific examples that appear in the Mixer's configuration. -### Proto `map`s and `message`s map to JSON objects: +### Proto `map` and `message` translate to JSON objects: @@ -51,7 +51,7 @@ message Metric { *Note that a map's keys are always converted to strings, no matter the data type declared in the proto file. They are converted back to the correct runtime type by the proto parsing libraries.* -### A `repeated` Proto field maps to a JSON array: +### Proto `repeated` fields translate to JSON arrays:
    @@ -102,7 +102,7 @@ message MetricsParams { *Note that we never name the outer-most message (the `MetricsParams`), but we do need the outer set of braces marking our JSON as an object.* -### A proto `enum` field uses the name of the value you want to specify: +### Proto `enum` fields uses the name of the value:
    @@ -141,7 +141,7 @@ message AttributeDescriptor { *Notice we don't provide a `description`: fields with no value can be omitted.* -### `message` fields can contain other messages: +### Proto `message` fields can contain other messages:
    @@ -202,7 +202,7 @@ There is no canonical mapping between protobufs and YAML; instead protobuf defin - JSON objects map to a set of field names all at the same indentation level in YAML - YAML is whitespace sensitive and must use spaces; tabs are never allowed -### `map`s and `message`s: +### Proto `map` and `message` fields:
    @@ -247,7 +247,7 @@ labels: *Note that when numeric literals are used as strings (like `value` above) they must be enclosed in quotes. Quotation marks (`"`) are optional for normal strings.* -### `repeated` fields: +### Proto `repeated` fields:
    @@ -311,7 +311,7 @@ metrics:
    -### `enum` fields: +### Proto `enum` fields: @@ -363,7 +363,7 @@ valueType: INT64 *Note that YAML parsing will handle both `snake_case` and `camelCase` field names.* -### Nested `message`s: +### Proto with nested `message` fields:
    From 8a2ee95a151620855eec45205e5baba8210a8759 Mon Sep 17 00:00:00 2001 From: Zack Date: Mon, 10 Apr 2017 16:47:35 -0700 Subject: [PATCH 3/6] Swap to lowerCamelCase for JSON and YAML fields in accordance with the canonical mapping. --- docs/concepts/writing-config.md | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/concepts/writing-config.md b/docs/concepts/writing-config.md index 4439a7afb9..7f4c60b840 100644 --- a/docs/concepts/writing-config.md +++ b/docs/concepts/writing-config.md @@ -36,7 +36,7 @@ message Metric {
     {
    -  "descriptor_name": "request_count",
    +  "descriptorName": "request_count",
       "value": "1",
       "labels": {
           "source": "origin.ip",
    @@ -61,7 +61,7 @@ message Metric {
       
    -
    +
    `
     message Metric {
             string descriptor_name = 1;
             string value = 2;
    @@ -78,14 +78,14 @@ message MetricsParams {
     {
       "metrics": [
         {
    -      "descriptor_name": "request_count",
    +      "descriptorName": "request_count",
           "value": "1",
           "labels": {
                 "source": "origin.ip",
                 "target": "target.service",
           },
         }, {
    -      "descriptor_name": "request_latency",
    +      "descriptorName": "request_latency",
           "value": "response.duration",
           "labels": {
                 "source": "origin.ip",
    @@ -100,7 +100,7 @@ message MetricsParams {
     
    -*Note that we never name the outer-most message (the `MetricsParams`), but we do need the outer set of braces marking our JSON as an object.* +*Note that we never name the outer-most message (the `MetricsParams`), but we do need the outer set of braces marking our JSON as an object. Also note that we shift from snake_case to lowerCamelCase; both are accepted but lowerCamelCase is idiomatic.* ### Proto `enum` fields uses the name of the value: @@ -131,7 +131,7 @@ message AttributeDescriptor {
     {
       "name": "request.duration",
    -  "value_type": "INT64",
    +  "valueType": "INT64",
     }
     
    @@ -178,10 +178,10 @@ message MonitoredResourceDescriptor { "labels": [ { "name": "label one", - "value_type": "STRING", + "valueType": "STRING", }, { "name": "second label", - "value_type": "DOUBLE", + "valueType": "DOUBLE", }, ], } @@ -223,18 +223,18 @@ message Metric {
     {
    -  "descriptor_name": "request_count",
    +  "descriptorName": "request_count",
       "value": "1",
       "labels": {
           "source": "origin.ip",
    -        "target": "target.service",
    +      "target": "target.service",
       },
     }  
     
    -descriptor_name: request_count
    +descriptorName: request_count
     value: "1"
     labels:
       source: origin.ip
    @@ -274,14 +274,14 @@ message MetricsParams {
     {
       "metrics": [
         {
    -      "descriptor_name": "request_count",
    +      "descriptorName": "request_count",
           "value": "1",
           "labels": {
                 "source": "origin.ip",
                 "target": "target.service",
           },
         }, {
    -      "descriptor_name": "request_latency",
    +      "descriptorName": "request_latency",
           "value": "response.duration",
           "labels": {
                 "source": "origin.ip",
    @@ -295,12 +295,12 @@ message MetricsParams {
         
     
     metrics:
    -- descriptor_name: request_count
    +- descriptorName: request_count
       value: "1"
       labels:
         source: origin.ip
         target: target.service
    -- descriptor_name: request_latency
    +- descriptorName: request_latency
       value: response.duration
       labels:
         source: origin.ip
    @@ -340,14 +340,14 @@ message AttributeDescriptor {
     
     {
       "name": "request.duration",
    -  "value_type": "INT64",
    +  "valueType": "INT64",
     }
     
     name: request.duration
    -value_type: INT64
    +valueType: INT64
     
    or @@ -401,10 +401,10 @@ message MonitoredResourceDescriptor { "labels": [ { "name": "label one", - "value_type": "STRING", + "valueType": "STRING", }, { "name": "second label", - "value_type": "DOUBLE", + "valueType": "DOUBLE", }, ], } @@ -415,9 +415,9 @@ message MonitoredResourceDescriptor { name: My Monitored Resource labels: - name: label one - value_type: STRING + valueType: STRING - name: second label - value_type: DOUBLE + valueType: DOUBLE
    From 6ac4405c027491ef90fb07c37da58656a455b7d0 Mon Sep 17 00:00:00 2001 From: Zack Date: Wed, 12 Apr 2017 10:44:22 -0700 Subject: [PATCH 4/6] Remove JSON examples --- docs/concepts/writing-config.md | 257 ++------------------------------ 1 file changed, 9 insertions(+), 248 deletions(-) diff --git a/docs/concepts/writing-config.md b/docs/concepts/writing-config.md index 7f4c60b840..be851989cc 100644 --- a/docs/concepts/writing-config.md +++ b/docs/concepts/writing-config.md @@ -12,202 +12,22 @@ This document describes how to write configuration that conforms to Istio's sche {% endcapture %} {% capture body %} -## Translating to JSON -The protobuf language guide defines [the canonical mapping between protobuf and JSON](https://developers.google.com/protocol-buffers/docs/proto3#json), refer to it as the source of truth. We provide a few specific examples that appear in the Mixer's configuration. - -### Proto `map` and `message` translate to JSON objects: - - - - - - - - - - - - -
    ProtoJSON
    -
    -message Metric {
    -        string descriptor_name = 1;
    -        string value = 2;
    -        map labels = 3;
    -}
    -
    -
    -
    -{
    -  "descriptorName": "request_count",
    -  "value": "1",
    -  "labels": {
    -      "source": "origin.ip",
    -        "target": "target.service",
    -  },
    -}  
    -
    -
    - -*Note that a map's keys are always converted to strings, no matter the data type declared in the proto file. They are converted back to the correct runtime type by the proto parsing libraries.* - -### Proto `repeated` fields translate to JSON arrays: - - - - - - - - - - - - -
    ProtoJSON
    -
    `
    -message Metric {
    -        string descriptor_name = 1;
    -        string value = 2;
    -        map labels = 3;
    -}
    -
    -message MetricsParams {
    -    repeated Metric metrics = 1;
    -}
    -
    -
    -
    -{
    -  "metrics": [
    -    {
    -      "descriptorName": "request_count",
    -      "value": "1",
    -      "labels": {
    -            "source": "origin.ip",
    -            "target": "target.service",
    -      },
    -    }, {
    -      "descriptorName": "request_latency",
    -      "value": "response.duration",
    -      "labels": {
    -            "source": "origin.ip",
    -            "target": "target.service",
    -      },
    -    }
    -  ]
    -}  
    -
    -
    - -*Note that we never name the outer-most message (the `MetricsParams`), but we do need the outer set of braces marking our JSON as an object. Also note that we shift from snake_case to lowerCamelCase; both are accepted but lowerCamelCase is idiomatic.* - -### Proto `enum` fields uses the name of the value: - - - - - - - - - - - - -
    ProtoJSON
    -
    -enum ValueType {
    -    STRING = 1;
    -    INT64 = 2;
    -    DOUBLE = 3;
    -    // more values omitted
    -}
    -
    -message AttributeDescriptor {
    -    string name = 1;
    -    string description = 2;
    -    ValueType value_type = 3;
    -}
    -
    -
    -
    -{
    -  "name": "request.duration",
    -  "valueType": "INT64",
    -}
    -
    -
    - -*Notice we don't provide a `description`: fields with no value can be omitted.* - -### Proto `message` fields can contain other messages: - - - - - - - - - - - -
    ProtoJSON
    -
    -enum ValueType {
    -    STRING = 1;
    -    INT64 = 2;
    -    DOUBLE = 3;
    -    // more values omitted
    -}
    -
    -message LabelDescriptor {
    -    string name = 1;
    -    string description = 2;
    -    ValueType value_type = 3;
    -}
    -
    -message MonitoredResourceDescriptor {
    -  string name = 1;
    -  string description = 2;
    -  repeated LabelDescriptor labels = 3;
    -}
    -
    -
    -
    -{
    -  "name": "My Monitored Resource",
    -  "labels": [
    -    {
    -      "name": "label one",
    -      "valueType": "STRING",
    -    }, {
    -      "name": "second label",
    -      "valueType": "DOUBLE",
    -    },
    -  ],
    -}
    -
    -
    - ## Translating to YAML - -There is no canonical mapping between protobufs and YAML; instead protobuf defines a canonical mapping to JSON, and YAML defines a canonical mapping to JSON. To ingest YAML as a proto we convert it to JSON then to protobuf. +There is no canonical mapping between protobufs and YAML; instead [protobuf defines a canonical mapping to JSON](https://developers.google.com/protocol-buffers/docs/proto3#json), and [YAML defines a canonical mapping to JSON](http://yaml.org/spec/1.2/spec.html#id2759572). To ingest YAML as a proto we convert it to JSON then to protobuf. **Important things to note:** - YAML fields are implicitly strings -- JSON arrays map to YAML lists; each element in a list is prefixed by a dash (`-`) -- JSON objects map to a set of field names all at the same indentation level in YAML +- Proto `repeated` fields map to YAML lists; each element in a YAML list is prefixed by a dash (`-`) +- Proto `message`s map to JSON objects; in YAML objects are field names all at the same indentation level - YAML is whitespace sensitive and must use spaces; tabs are never allowed ### Proto `map` and `message` fields: + - @@ -222,18 +42,6 @@ message Metric { -
    ProtoJSON YAML
    -{
    -  "descriptorName": "request_count",
    -  "value": "1",
    -  "labels": {
    -      "source": "origin.ip",
    -      "target": "target.service",
    -  },
    -}  
    -
    -
    -
     descriptorName: request_count
     value: "1"
     labels:
    @@ -248,11 +56,11 @@ labels:
     *Note that when numeric literals are used as strings (like `value` above) they must be enclosed in quotes. Quotation marks (`"`) are optional for normal strings.*
     
     ### Proto `repeated` fields:
    +
     
    -    
    @@ -271,29 +79,6 @@ message MetricsParams {
         
    -    
    ProtoJSON YAML
    -{
    -  "metrics": [
    -    {
    -      "descriptorName": "request_count",
    -      "value": "1",
    -      "labels": {
    -            "source": "origin.ip",
    -            "target": "target.service",
    -      },
    -    }, {
    -      "descriptorName": "request_latency",
    -      "value": "response.duration",
    -      "labels": {
    -            "source": "origin.ip",
    -            "target": "target.service",
    -      },
    -    }
    -  ]
    -}  
    -
    -
    -
     metrics:
     - descriptorName: request_count
       value: "1"
    @@ -312,11 +97,11 @@ metrics:
     
    ### Proto `enum` fields: + - @@ -338,16 +123,8 @@ message AttributeDescriptor { -
    ProtoJSON YAML
    -{
    -  "name": "request.duration",
    -  "valueType": "INT64",
    -}
    -
    -
    -
     name: request.duration
    -valueType: INT64
    +value_type: INT64
     
    or @@ -361,14 +138,14 @@ valueType: INT64
    -*Note that YAML parsing will handle both `snake_case` and `camelCase` field names.* +*Note that YAML parsing will handle both `snake_case` and `lowerCamelCase` field names. `lowerCamelCase` is the canonical version in YAML.* ### Proto with nested `message` fields: + - @@ -396,22 +173,6 @@ message MonitoredResourceDescriptor { -
    ProtoJSON YAML
    -{
    -  "name": "My Monitored Resource",
    -  "labels": [
    -    {
    -      "name": "label one",
    -      "valueType": "STRING",
    -    }, {
    -      "name": "second label",
    -      "valueType": "DOUBLE",
    -    },
    -  ],
    -}
    -
    -
    -
     name: My Monitored Resource
     labels:
     - name: label one
    
    From 5ea6fdafe499410c1eea0f4633f44ac14a87ce43 Mon Sep 17 00:00:00 2001
    From: Zack 
    Date: Wed, 12 Apr 2017 10:45:38 -0700
    Subject: [PATCH 5/6] Address a few more review comments
    
    ---
     docs/concepts/writing-config.md | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/docs/concepts/writing-config.md b/docs/concepts/writing-config.md
    index be851989cc..5c8481f50f 100644
    --- a/docs/concepts/writing-config.md
    +++ b/docs/concepts/writing-config.md
    @@ -1,6 +1,6 @@
     ---
    -title: Writing Istio Configuration
    -headline: Writing Istio Configuration
    +title: Writing Configuration
    +headline: Writing Configuration
     sidenav: doc-side-concepts-nav.html
     bodyclass: docs
     layout: docs
    @@ -8,7 +8,7 @@ type: markdown
     ---
     
     {% capture overview %}
    -This document describes how to write configuration that conforms to Istio's schemas. All configuration schemas in Istio are defined as protobuf messages. When in doubt, search for the protos.
    +This document describes how to write configuration that conforms to Istio's schemas. All configuration schemas in Istio are defined as [protobuf messages](https://developers.google.com/protocol-buffers/docs/proto3). When in doubt, search for the protos.
     {% endcapture %}
     
     {% capture body %}
    
    From 138606f0bbf3e95a3e382c0ffad36088d39cf929 Mon Sep 17 00:00:00 2001
    From: Zack 
    Date: Thu, 13 Apr 2017 10:21:34 -0700
    Subject: [PATCH 6/6] Remove 'Proto' from the various section headings
    
    ---
     docs/concepts/writing-config.md | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/docs/concepts/writing-config.md b/docs/concepts/writing-config.md
    index 5c8481f50f..2da72c19d3 100644
    --- a/docs/concepts/writing-config.md
    +++ b/docs/concepts/writing-config.md
    @@ -22,7 +22,7 @@ There is no canonical mapping between protobufs and YAML; instead [protobuf defi
     - Proto `message`s map to JSON objects; in YAML objects are field names all at the same indentation level
     - YAML is whitespace sensitive and must use spaces; tabs are never allowed
     
    -### Proto `map` and `message` fields:
    +### `map` and `message` fields
     
     
    @@ -55,7 +55,7 @@ labels:
     
     *Note that when numeric literals are used as strings (like `value` above) they must be enclosed in quotes. Quotation marks (`"`) are optional for normal strings.*
     
    -### Proto `repeated` fields:
    +### `repeated` fields
     
     
    @@ -96,7 +96,7 @@ metrics:
    -### Proto `enum` fields: +### `enum` fields @@ -140,7 +140,7 @@ valueType: INT64 *Note that YAML parsing will handle both `snake_case` and `lowerCamelCase` field names. `lowerCamelCase` is the canonical version in YAML.* -### Proto with nested `message` fields: +### Nested `message` fields