Repository: awslabs/cdk8s (ts)

Issue:
Multiline configmap data produces output with lines separated by empty lines
Multiline configmap data produces output with lines separated by empty lines
---------------------------------

The output of the [suggestion #86 ](https://github.com/awslabs/cdk8s/issues/86) is a little off (i.e. not pretty). For example, with the snippet below:
You will get a yaml file with empty lines in between each line in the array. 
To contrast, running `console.log(daemonfile)` in TypeScript playground(/node for the compiled javascript),  the multiline output has no empty lines in between (as required).

In the end the yaml is a little chunkier than it should be. Am I missing something here?

```typescript
let daemonfile = [
            "# Maximum buffer size in MB (minimum 3). Choose 0 to use 1% of host memory. ",
            "TotalBufferSizeMB: 0",
            "# Maximum number of concurrent calls to AWS X-Ray to upload segment documents.",
            "Concurrency: 8",
            "# Send segments to AWS X-Ray service in a specific region",
            "Region: \"\"",
            "# Change the X-Ray service endpoint to which the daemon sends segment documents.",
            "Endpoint: \"\"",
            "Socket:",
            "  # Change the address and port on which the daemon listens for UDP packets containing segment documents.",
            "  # Make sure we listen on all IP's by default for the k8s setup",
            "  UDPAddress: 0.0.0.0:2000",
            "Logging:",
            "  LogRotation: true",
            "  # Change the log level, from most verbose to least: dev, debug, info, warn, error, prod (default).",
            "  LogLevel: prod",
            "  # Output logs to the specified file path.",
            "  LogPath: \"\"",
            "# Turn on local mode to skip EC2 instance metadata check.",
            "LocalMode: false",
            "# Amazon Resource Name (ARN) of the AWS resource running the daemon.",
            "ResourceARN: \"\"",
            "# Assume an IAM role to upload segments to a different account.",
            "RoleARN: \"\"",
            "# Disable TLS certificate verification.",
            "NoVerifySSL: false",
            "# Upload segments to AWS X-Ray through a proxy.",
            "ProxyAddress: \"\"",
            "# Daemon configuration file format version.",
            "Version: 1"
        ].join("\n");

        new ConfigMap(scope, "xray-config", {
            data: {
                "config.yaml": daemonfile
            }
        });
```

I also tried with the another pattern, i.e. using a back tick **`** e.g.
The output wasn't any better:

``` TypeScript
let daemonfile = `
line1
line2
...
`
new ConfigMap(scope, "xray-config", {
            data: {
                "config.yaml": daemonfile
            }
        });
```

I could not get away with trying regex to replace new lines as well, e.g. 
``` TypeScript
const regex = new RegExp("\n{2,}",'gi');
let daemonfile = [
            "# Maximum buffer size in MB (minimum 3). Choose 0 to use 1% of host memory. ",
            "TotalBufferSizeMB: 0",
            "# Maximum number of concurrent calls to AWS X-Ray to upload segment documents.",
            "Concurrency: 8",
            "# Send segments to AWS X-Ray service in a specific region",
            "Region: \"\"",
...
]
].join("\n").replace(regex, "");

new ConfigMap(scope, "xray-config", {
            data: {
                "config.yaml": daemonfile
            }
        });
```

Pull request:
fix: set yaml default schema to 1.1
*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*

---
Currently, the output of multiline strings is very ugly in the rendered YAML files; there are many extra newlines and backslashes, majorly hurting readability.

To fix #172, this PR returns to the default YAML string settings that allow the parser to decide between double-quoting or creating a block-literal from a string. 

To ensure we don't bring back the issues from #325, this PR also sets the default YAML schema to `yaml-1.1`, to retain compatibility with most other YAML parsers' default settings.

Aside from the tests in the PR, I have also confirmed this fix against the repro steps in #325.

Patch:
diff --git a/packages/cdk8s/src/yaml.ts b/packages/cdk8s/src/yaml.ts
index b4ce971fd..bf0d2ca28 100644
--- a/packages/cdk8s/src/yaml.ts
+++ b/packages/cdk8s/src/yaml.ts
@@ -3,13 +3,13 @@ import * as fs from 'fs';
 import * as os from 'os';
 import * as path from 'path';
 import * as YAML from 'yaml';
-import { Type } from 'yaml/util';
 
 const MAX_DOWNLOAD_BUFFER = 10 * 1024 * 1024;
 
-// Ensure that all strings are quoted when written to yaml to avoid unquoted
-// primitive types in the output yaml in fields that require strings.
-YAML.scalarOptions.str.defaultType = Type.QUOTE_DOUBLE;
+// Set default YAML schema to 1.1. This ensures saved YAML is backward compatible with other parsers, such as PyYAML
+// It also ensures that octal numbers in the form `0775` will be parsed
+// correctly on YAML load. (see https://github.com/eemeli/yaml/issues/205)
+YAML.defaultOptions.schema = 'yaml-1.1';
 
 /**
  * YAML utilities.
@@ -55,9 +55,7 @@ export class Yaml {
   public static load(urlOrFile: string): any[] {
     const body = loadurl(urlOrFile);
 
-    // we need to use yaml-1.1 so that octal numbers in the form `0775` will be parsed
-    // correctly (see https://github.com/eemeli/yaml/issues/205)
-    const objects = YAML.parseAllDocuments(body, { schema: 'yaml-1.1' });
+    const objects = YAML.parseAllDocuments(body);
     const result = new Array<any>();
 
     for (const obj of objects.map(x => x.toJSON())) {


Test patch:
diff --git a/packages/cdk8s/test/__snapshots__/yaml.test.ts.snap b/packages/cdk8s/test/__snapshots__/yaml.test.ts.snap
index dd4ace518..1783dac6b 100644
--- a/packages/cdk8s/test/__snapshots__/yaml.test.ts.snap
+++ b/packages/cdk8s/test/__snapshots__/yaml.test.ts.snap
@@ -278,7 +278,7 @@ empty_object: {}
 `;
 
 exports[`save multiple documents 1`] = `
-"foo: \\"bar\\"
+"foo: bar
 hello:
   - 1
   - 2
@@ -289,7 +289,7 @@ number: 2
 `;
 
 exports[`save single document 1`] = `
-"foo: \\"bar\\"
+"foo: bar
 hello:
   - 1
   - 2
@@ -299,7 +299,7 @@ hello:
 
 exports[`save strings are quoted 1`] = `
 "foo: \\"on\\"
-bar: \\"this has a \\\\\\"big quote\\\\\\"\\"
+bar: this has a \\"big quote\\"
 not_a_string: true
 "
 `;
diff --git a/test/test-java-app/expected/test.k8s.yaml b/test/test-java-app/expected/test.k8s.yaml
index 6d05bc29a..1900919ab 100644
--- a/test/test-java-app/expected/test.k8s.yaml
+++ b/test/test-java-app/expected/test.k8s.yaml
@@ -1,10 +1,10 @@
-apiVersion: "v1"
-kind: "Pod"
+apiVersion: v1
+kind: Pod
 metadata:
-  name: "test-pod-c815bc91"
+  name: test-pod-c815bc91
 spec:
   containers:
-    - image: "paulbower/hello-kubernetes:1.7"
-      name: "hello-kubernetes"
+    - image: paulbower/hello-kubernetes:1.7
+      name: hello-kubernetes
       ports:
         - containerPort: 8080
diff --git a/test/test-python-app/expected/test.k8s.yaml b/test/test-python-app/expected/test.k8s.yaml
index 828c88d3d..99d5343ab 100644
--- a/test/test-python-app/expected/test.k8s.yaml
+++ b/test/test-python-app/expected/test.k8s.yaml
@@ -1,10 +1,10 @@
-apiVersion: "v1"
-kind: "Pod"
+apiVersion: v1
+kind: Pod
 metadata:
-  name: "test-pod-c82fd911"
+  name: test-pod-c82fd911
 spec:
   containers:
-    - image: "paulbouwer/hello-kubernetes:1.7"
-      name: "hello-kubernetes"
+    - image: paulbouwer/hello-kubernetes:1.7
+      name: hello-kubernetes
       ports:
         - containerPort: 8080
diff --git a/test/test-typescript-app/expected/test.k8s.yaml b/test/test-typescript-app/expected/test.k8s.yaml
index 828c88d3d..99d5343ab 100644
--- a/test/test-typescript-app/expected/test.k8s.yaml
+++ b/test/test-typescript-app/expected/test.k8s.yaml
@@ -1,10 +1,10 @@
-apiVersion: "v1"
-kind: "Pod"
+apiVersion: v1
+kind: Pod
 metadata:
-  name: "test-pod-c82fd911"
+  name: test-pod-c82fd911
 spec:
   containers:
-    - image: "paulbouwer/hello-kubernetes:1.7"
-      name: "hello-kubernetes"
+    - image: paulbouwer/hello-kubernetes:1.7
+      name: hello-kubernetes
       ports:
         - containerPort: 8080