{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/77912820","id":77912820,"diff_hunk":"@@ -0,0 +1,544 @@\n+/*\n+Copyright 2016 The Kubernetes Authors.\n+\n+Licensed under the Apache License, Version 2.0 (the \"License\");\n+you may not use this file except in compliance with the License.\n+You may obtain a copy of the License at\n+\n+    http://www.apache.org/licenses/LICENSE-2.0\n+\n+Unless required by applicable law or agreed to in writing, software\n+distributed under the License is distributed on an \"AS IS\" BASIS,\n+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+See the License for the specific language governing permissions and\n+limitations under the License.\n+*/\n+\n+package generators\n+\n+import (\n+\t\"bytes\"\n+\t\"fmt\"\n+\t\"io\"\n+\t\"path/filepath\"\n+\t\"reflect\"\n+\t\"sort\"\n+\t\"strings\"\n+\n+\t\"k8s.io/kubernetes/cmd/libs/go2idl/args\"\n+\t\"k8s.io/kubernetes/cmd/libs/go2idl/generator\"\n+\t\"k8s.io/kubernetes/cmd/libs/go2idl/namer\"\n+\t\"k8s.io/kubernetes/cmd/libs/go2idl/types\"\n+\t\"k8s.io/kubernetes/pkg/util/sets\"\n+\n+\t\"github.com/go-openapi/spec\"\n+\t\"github.com/golang/glog\"\n+)\n+\n+// OpenAPIDefinition describes single type. Normally these definitions are auto-generated using gen-openapi.\n+type OpenAPIDefinition struct {\n+\tSchema       spec.Schema\n+\tDependencies []string\n+}\n+\n+// OpenAPIDefinitions is collection of all definitions.\n+type OpenAPIDefinitions map[string]OpenAPIDefinition\n+\n+// OpenAPIGetDefinition describe types that can customize openAPI definitions. If a type implements this interface, the definition returns\n+// by it will be used, otherwise the auto-generated definitions will be used.\n+type OpenAPIGetDefinition interface {\n+\tOpenAPIDefinition() *OpenAPIDefinition\n+}\n+\n+// This is the comment tag that carries parameters for open API generation.\n+const tagName = \"k8s:openapi-gen\"\n+\n+// Known values for the tag.\n+const (\n+\ttagValueTrue  = \"true\"\n+\ttagValueFalse = \"false\"\n+\t// Should only be used only for test\n+\ttagTargetType = \"target\"\n+)\n+\n+func hasOpenAPITagValue(comments []string, value string) bool {\n+\ttagValues := types.ExtractCommentTags(\"+\", comments)[tagName]\n+\tif tagValues == nil {\n+\t\treturn false\n+\t}\n+\tfor _, val := range tagValues {\n+\t\tif val == value {\n+\t\t\treturn true\n+\t\t}\n+\t}\n+\treturn false\n+}\n+\n+// NameSystems returns the name system used by the generators in this package.\n+func NameSystems() namer.NameSystems {\n+\treturn namer.NameSystems{\n+\t\t\"raw\": namer.NewRawNamer(\"\", nil),\n+\t}\n+}\n+\n+// DefaultNameSystem returns the default name system for ordering the types to be\n+// processed by the generators in this package.\n+func DefaultNameSystem() string {\n+\treturn \"raw\"\n+}\n+\n+func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {\n+\tboilerplate, err := arguments.LoadGoBoilerplate()\n+\tif err != nil {\n+\t\tglog.Fatalf(\"Failed loading boilerplate: %v\", err)\n+\t}\n+\tinputs := sets.NewString(context.Inputs...)\n+\theader := append([]byte(fmt.Sprintf(\"// +build !%s\\n\\n\", arguments.GeneratedBuildTag)), boilerplate...)\n+\theader = append(header, []byte(\n+\t\t`\n+// This file was autogenerated by openapi-gen. Do not edit it manually!\n+\n+`)...)\n+\n+\ttargets := []*types.Type{}\n+\tfor i := range inputs {\n+\t\tglog.V(5).Infof(\"considering pkg %q\", i)\n+\t\tpkg := context.Universe[i]\n+\t\tif pkg == nil {\n+\t\t\t// If the input had no Go files, for example.\n+\t\t\tcontinue\n+\t\t}\n+\t\tfor _, t := range pkg.Types {\n+\t\t\tif hasOpenAPITagValue(t.CommentLines, tagTargetType) {\n+\t\t\t\tglog.V(5).Infof(\"target type : %q\", t)\n+\t\t\t\ttargets = append(targets, t)\n+\t\t\t}\n+\t\t}\n+\t}\n+\tswitch len(targets) {\n+\tcase 0:\n+\t\t// If no target package found, that means the generated file in target package is up to date\n+\t\t// and build excluded the target package.\n+\t\treturn generator.Packages{}\n+\tcase 1:\n+\t\tpkg := context.Universe[targets[0].Name.Package]\n+\t\treturn generator.Packages{&generator.DefaultPackage{\n+\t\t\tPackageName: strings.Split(filepath.Base(pkg.Path), \".\")[0],\n+\t\t\tPackagePath: pkg.Path,\n+\t\t\tHeaderText:  header,\n+\t\t\tGeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {\n+\t\t\t\treturn []generator.Generator{NewOpenAPIGen(arguments.OutputFileBaseName, pkg.Path, targets[0], context)}\n+\t\t\t},\n+\t\t\tFilterFunc: func(c *generator.Context, t *types.Type) bool {\n+\t\t\t\t// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen\n+\t\t\t\tif strings.HasPrefix(t.Name.Name, \"codecSelfer\") {\n+\t\t\t\t\treturn false\n+\t\t\t\t}\n+\t\t\t\tpkg := context.Universe.Package(t.Name.Package)\n+\t\t\t\tif hasOpenAPITagValue(pkg.Comments, tagValueTrue) {\n+\t\t\t\t\treturn !hasOpenAPITagValue(t.CommentLines, tagValueFalse)\n+\t\t\t\t}\n+\t\t\t\tif hasOpenAPITagValue(t.CommentLines, tagValueTrue) {\n+\t\t\t\t\treturn true\n+\t\t\t\t}\n+\t\t\t\treturn false\n+\t\t\t},\n+\t\t},\n+\t\t}\n+\tdefault:\n+\t\tglog.Fatalf(\"Duplicate target type found: %v\", targets)\n+\t}\n+\treturn generator.Packages{}\n+}\n+\n+const (\n+\tspecPackagePath       = \"github.com/go-openapi/spec\"\n+\topenAPIGenPackagePath = \"k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen/generators\"\n+)\n+\n+// openApiGen produces a file with auto-generated OpenAPI functions.\n+type openAPIGen struct {\n+\tgenerator.DefaultGen\n+\ttargetPackage string\n+\timports       namer.ImportTracker\n+\ttargetType    *types.Type\n+\tcontext       *generator.Context\n+}\n+\n+func NewOpenAPIGen(sanitizedName, targetPackage string, targetType *types.Type, context *generator.Context) generator.Generator {\n+\treturn &openAPIGen{\n+\t\tDefaultGen: generator.DefaultGen{\n+\t\t\tOptionalName: sanitizedName,\n+\t\t},\n+\t\ttargetPackage: targetPackage,\n+\t\timports:       generator.NewImportTracker(),\n+\t\ttargetType:    targetType,\n+\t\tcontext:       context,\n+\t}\n+}\n+\n+func (g *openAPIGen) Namers(c *generator.Context) namer.NameSystems {\n+\t// Have the raw namer for this file track what it imports.\n+\treturn namer.NameSystems{\n+\t\t\"raw\": namer.NewRawNamer(g.targetPackage, g.imports),\n+\t}\n+}\n+\n+func (g *openAPIGen) Filter(c *generator.Context, t *types.Type) bool {\n+\t// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen\n+\tif strings.HasPrefix(t.Name.Name, \"codecSelfer\") {\n+\t\treturn false\n+\t}\n+\treturn true\n+}\n+\n+func (g *openAPIGen) isOtherPackage(pkg string) bool {\n+\tif pkg == g.targetPackage {\n+\t\treturn false\n+\t}\n+\tif strings.HasSuffix(pkg, \"\\\"\"+g.targetPackage+\"\\\"\") {\n+\t\treturn false\n+\t}\n+\treturn true\n+}\n+\n+func (g *openAPIGen) Imports(c *generator.Context) []string {\n+\timportLines := []string{}\n+\tfor _, singleImport := range g.imports.ImportLines() {\n+\t\tif g.isOtherPackage(singleImport) {\n+\t\t\timportLines = append(importLines, singleImport)\n+\t\t}\n+\t}\n+\treturn importLines\n+}\n+\n+func argsFromType(t *types.Type) generator.Args {\n+\treturn generator.Args{\n+\t\t\"type\":               t,\n+\t\t\"OpenAPIDefinitions\": types.Ref(openAPIGenPackagePath, \"OpenAPIDefinitions\"),\n+\t\t\"OpenAPIDefinition\":  types.Ref(openAPIGenPackagePath, \"OpenAPIDefinition\"),\n+\t\t\"SpecSchemaType\":     types.Ref(specPackagePath, \"Schema\"),\n+\t}\n+}\n+\n+func (g *openAPIGen) Init(c *generator.Context, w io.Writer) error {\n+\tsw := generator.NewSnippetWriter(w, c, \"$\", \"$\")\n+\tsw.Do(\"func (_ $.type|raw$) OpenAPIDefinitions() *$.OpenAPIDefinitions|raw$ {\\n\", argsFromType(g.targetType))\n+\tsw.Do(\"return &$.OpenAPIDefinitions|raw${\\n\", argsFromType(nil))\n+\treturn sw.Error()\n+}\n+\n+func (g *openAPIGen) Finalize(c *generator.Context, w io.Writer) error {\n+\tsw := generator.NewSnippetWriter(w, c, \"$\", \"$\")\n+\tsw.Do(\"}\\n}\\n\", nil)\n+\treturn sw.Error()\n+}\n+\n+func (g *openAPIGen) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {\n+\tglog.V(5).Infof(\"generating for type %v\", t)\n+\tsw := generator.NewSnippetWriter(w, c, \"$\", \"$\")\n+\terr := newOpenAPITypeWriter(sw).generate(t)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\treturn sw.Error()\n+}\n+\n+func getJsonTags(m *types.Member) []string {\n+\tjsonTag := reflect.StructTag(m.Tags).Get(\"json\")\n+\tif jsonTag == \"\" {\n+\t\treturn []string{}\n+\t}\n+\treturn strings.Split(jsonTag, \",\")\n+}\n+\n+func getReferableName(m *types.Member) string {\n+\tjsonTags := getJsonTags(m)\n+\tif len(jsonTags) > 0 {\n+\t\tif jsonTags[0] == \"-\" {\n+\t\t\treturn \"\"\n+\t\t} else {\n+\t\t\treturn jsonTags[0]\n+\t\t}\n+\t} else {\n+\t\treturn m.Name\n+\t}\n+}\n+\n+func isPropertyRequired(m *types.Member) bool {\n+\tjsonTags := getJsonTags(m)\n+\t// A property is required if it does not have omitempty value in its json tag\n+\treturn len(jsonTags) < 2 || jsonTags[1] != \"omitempty\"\n+}\n+\n+type openAPITypeWriter struct {\n+\t*generator.SnippetWriter\n+\trefTypes               map[string]*types.Type\n+\tGetDefinitionInterface *types.Type\n+}\n+\n+func newOpenAPITypeWriter(sw *generator.SnippetWriter) openAPITypeWriter {\n+\treturn openAPITypeWriter{\n+\t\tSnippetWriter: sw,\n+\t\trefTypes:      map[string]*types.Type{},\n+\t}\n+}\n+\n+func hasOpenAPIDefinitionMethod(t *types.Type) bool {\n+\tfor mn, mt := range t.Methods {\n+\t\tif mn != \"OpenAPIDefinition\" {\n+\t\t\tcontinue\n+\t\t}\n+\t\tif len(mt.Signature.Parameters) != 0 || len(mt.Signature.Results) != 1 {\n+\t\t\treturn false\n+\t\t}\n+\t\tr := mt.Signature.Results[0]\n+\t\tif r.Name.Name != \"OpenAPIDefinition\" || r.Name.Package != openAPIGenPackagePath {\n+\t\t\tglog.Errorf(\"Err4 %v\", t)\n+\t\t\treturn false\n+\t\t}\n+\t\treturn true\n+\t}\n+\treturn false\n+}\n+\n+func (g openAPITypeWriter) generate(t *types.Type) error {\n+\t// Only generate for struct type and ignore the rest\n+\tswitch t.Kind {\n+\tcase types.Struct:\n+\t\targs := argsFromType(t)\n+\t\tg.Do(\"\\\"$.$\\\": \", filepath.Base(t.Name.Package)+\".\"+t.Name.Name)\n+\t\tif hasOpenAPIDefinitionMethod(t) {\n+\t\t\tg.Do(\"$.type|raw${}.OpenAPIDefinition(),\", args)\n+\t\t\treturn nil\n+\t\t}\n+\t\tg.Do(\"{\\nSchema: spec.Schema{\\nSchemaProps: spec.SchemaProps{\\n\", nil)\n+\t\tg.generateDescription(t.CommentLines)\n+\t\tg.Do(\"Properties: map[string]$.SpecSchemaType|raw${\\n\", args)\n+\t\trequired := []string{}\n+\t\tfor _, m := range t.Members {\n+\t\t\tname := getReferableName(&m)\n+\t\t\tif name == \"\" {\n+\t\t\t\tcontinue\n+\t\t\t}\n+\t\t\tif isPropertyRequired(&m) {\n+\t\t\t\trequired = append(required, name)\n+\t\t\t}\n+\t\t\tif err := g.generateProperty(&m); err != nil {\n+\t\t\t\treturn err\n+\t\t\t}\n+\t\t}\n+\t\tg.Do(\"},\\n\", nil)\n+\t\tif len(required) > 0 {\n+\t\t\tg.Do(\"Required: []string{\\\"$.$\\\"},\\n\", strings.Join(required, \"\\\",\\\"\"))\n+\t\t}\n+\t\tg.Do(\"},\\n},\\n\", nil)\n+\t\t// \t\t\t\tSchemaProps: spec.SchemaProps{\n+\n+\t\tg.Do(\"Dependencies: []string{\\n\", args)\n+\t\t// Map order is undefined, sort them or we may get a different file generated each time.\n+\t\tkeys := []string{}\n+\t\tfor k := range g.refTypes {\n+\t\t\tkeys = append(keys, k)\n+\t\t}\n+\t\tsort.Strings(keys)\n+\t\tfor _, k := range keys {\n+\t\t\tv := g.refTypes[k]\n+\t\t\tif t, _ := GetOpenAPITypeFormat(v.String()); t != \"\" {\n+\t\t\t\t// This is a known type, we do not need a reference to it\n+\t\t\t\t// Will eliminate special case of time.Time\n+\t\t\t\tcontinue\n+\t\t\t}\n+\t\t\tg.Do(\"\\\"$.$\\\",\", k)\n+\t\t}\n+\t\tg.Do(\"},\\n},\\n\", nil)\n+\t}\n+\treturn nil\n+}\n+\n+func (g openAPITypeWriter) generateDescription(CommentLines []string) {\n+\tvar buffer bytes.Buffer\n+\tdelPrevChar := func() {\n+\t\tif buffer.Len() > 0 {\n+\t\t\tbuffer.Truncate(buffer.Len() - 1) // Delete the last \" \" or \"\\n\"\n+\t\t}\n+\t}\n+\n+\tfor _, line := range CommentLines {\n+\t\t// Ignore all lines after ---\n+\t\tif line == \"---\" {\n+\t\t\tbreak\n+\t\t}\n+\t\tline = strings.TrimRight(line, \" \")\n+\t\tleading := strings.TrimLeft(line, \" \")\n+\t\tswitch {\n+\t\tcase len(line) == 0: // Keep paragraphs\n+\t\t\tdelPrevChar()\n+\t\t\tbuffer.WriteString(\"\\n\\n\")\n+\t\tcase strings.HasPrefix(leading, \"TODO\"): // Ignore one line TODOs\n+\t\tcase strings.HasPrefix(leading, \"+\"): // Ignore instructions to go2idl\n+\t\tdefault:\n+\t\t\tif strings.HasPrefix(line, \" \") || strings.HasPrefix(line, \"\\t\") {\n+\t\t\t\tdelPrevChar()\n+\t\t\t\tline = \"\\n\" + line + \"\\n\" // Replace it with newline. This is useful when we have a line with: \"Example:\\n\\tJSON-someting...\"\n+\t\t\t} else {\n+\t\t\t\tline += \" \"\n+\t\t\t}\n+\t\t\tbuffer.WriteString(line)\n+\t\t}\n+\t}\n+\n+\tpostDoc := strings.TrimRight(buffer.String(), \"\\n\")\n+\tpostDoc = strings.Replace(postDoc, \"\\\\\\\"\", \"\\\"\", -1) // replace user's \\\" to \"\n+\tpostDoc = strings.Replace(postDoc, \"\\\"\", \"\\\\\\\"\", -1) // Escape \"\n+\tpostDoc = strings.Replace(postDoc, \"\\n\", \"\\\\n\", -1)\n+\tpostDoc = strings.Replace(postDoc, \"\\t\", \"\\\\t\", -1)\n+\tpostDoc = strings.Trim(postDoc, \" \")\n+\tif postDoc != \"\" {\n+\t\tg.Do(\"Description: \\\"$.$\\\",\\n\", postDoc)\n+\t}\n+}\n+\n+func (g openAPITypeWriter) generateProperty(m *types.Member) error {\n+\tname := getReferableName(m)\n+\tif name == \"\" {\n+\t\treturn nil\n+\t}\n+\tg.Do(\"\\\"$.$\\\": {\\n\", name)\n+\tg.Do(\"SchemaProps: spec.SchemaProps{\\n\", nil)\n+\tg.generateDescription(m.CommentLines)\n+\tjsonTags := getJsonTags(m)\n+\tif len(jsonTags) > 1 && jsonTags[1] == \"string\" {\n+\t\tg.generateSimpleProperty(\"string\", \"\")\n+\t\tg.Do(\"},\\n},\\n\", nil)\n+\t\treturn nil\n+\t}\n+\tt := resolvedAliasType(m.Type)\n+\tif t.Kind == types.Pointer {\n+\t\tt = t.Elem\n+\t}\n+\tt = resolvedAliasType(t)","path":"cmd/libs/go2idl/openapi-gen/generators/openapi.go","position":420,"original_position":420,"commit_id":"1709b32b7ccb98303095c8114da9ff9451a1634d","original_commit_id":"1709b32b7ccb98303095c8114da9ff9451a1634d","user":{"login":"lavalamp","id":647318,"avatar_url":"https://avatars.githubusercontent.com/u/647318?v=3","gravatar_id":"","url":"https://api.github.com/users/lavalamp","html_url":"https://github.com/lavalamp","followers_url":"https://api.github.com/users/lavalamp/followers","following_url":"https://api.github.com/users/lavalamp/following{/other_user}","gists_url":"https://api.github.com/users/lavalamp/gists{/gist_id}","starred_url":"https://api.github.com/users/lavalamp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lavalamp/subscriptions","organizations_url":"https://api.github.com/users/lavalamp/orgs","repos_url":"https://api.github.com/users/lavalamp/repos","events_url":"https://api.github.com/users/lavalamp/events{/privacy}","received_events_url":"https://api.github.com/users/lavalamp/received_events","type":"User","site_admin":false},"body":"Two is a suspicious number of times to call a function. Should this be done in a loop? :)","created_at":"2016-09-07T22:03:26Z","updated_at":"2016-09-07T22:03:26Z","html_url":"https://github.com/kubernetes/kubernetes/pull/31468#discussion_r77912820","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/77912820"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/31468#discussion_r77912820"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468","id":82802709,"html_url":"https://github.com/kubernetes/kubernetes/pull/31468","diff_url":"https://github.com/kubernetes/kubernetes/pull/31468.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/31468.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/31468","number":31468,"state":"open","locked":false,"title":"Improvements on OpenAPI spec generation","user":{"login":"mbohlool","id":1613024,"avatar_url":"https://avatars.githubusercontent.com/u/1613024?v=3","gravatar_id":"","url":"https://api.github.com/users/mbohlool","html_url":"https://github.com/mbohlool","followers_url":"https://api.github.com/users/mbohlool/followers","following_url":"https://api.github.com/users/mbohlool/following{/other_user}","gists_url":"https://api.github.com/users/mbohlool/gists{/gist_id}","starred_url":"https://api.github.com/users/mbohlool/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbohlool/subscriptions","organizations_url":"https://api.github.com/users/mbohlool/orgs","repos_url":"https://api.github.com/users/mbohlool/repos","events_url":"https://api.github.com/users/mbohlool/events{/privacy}","received_events_url":"https://api.github.com/users/mbohlool/received_events","type":"User","site_admin":false},"body":"- Generating models using go2idl library (no reflection anymore)\r\n- Remove dependencies on go-restful/swagger\r\n- Generate one swagger.json file for each web-service\r\n- Bugfix: fixed a bug in trie implementation\r\n\r\nReference: #13414\n\n<!-- Reviewable:start -->\n---\nThis change is [<img src=\"https://reviewable.kubernetes.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.kubernetes.io/reviews/kubernetes/kubernetes/31468)\n<!-- Reviewable:end -->\n","created_at":"2016-08-25T22:14:59Z","updated_at":"2016-09-07T22:03:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"79d6db566da593099c5cd1b293457b69fb8d4f98","assignee":{"login":"lavalamp","id":647318,"avatar_url":"https://avatars.githubusercontent.com/u/647318?v=3","gravatar_id":"","url":"https://api.github.com/users/lavalamp","html_url":"https://github.com/lavalamp","followers_url":"https://api.github.com/users/lavalamp/followers","following_url":"https://api.github.com/users/lavalamp/following{/other_user}","gists_url":"https://api.github.com/users/lavalamp/gists{/gist_id}","starred_url":"https://api.github.com/users/lavalamp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lavalamp/subscriptions","organizations_url":"https://api.github.com/users/lavalamp/orgs","repos_url":"https://api.github.com/users/lavalamp/repos","events_url":"https://api.github.com/users/lavalamp/events{/privacy}","received_events_url":"https://api.github.com/users/lavalamp/received_events","type":"User","site_admin":false},"assignees":[{"login":"lavalamp","id":647318,"avatar_url":"https://avatars.githubusercontent.com/u/647318?v=3","gravatar_id":"","url":"https://api.github.com/users/lavalamp","html_url":"https://github.com/lavalamp","followers_url":"https://api.github.com/users/lavalamp/followers","following_url":"https://api.github.com/users/lavalamp/following{/other_user}","gists_url":"https://api.github.com/users/lavalamp/gists{/gist_id}","starred_url":"https://api.github.com/users/lavalamp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lavalamp/subscriptions","organizations_url":"https://api.github.com/users/lavalamp/orgs","repos_url":"https://api.github.com/users/lavalamp/repos","events_url":"https://api.github.com/users/lavalamp/events{/privacy}","received_events_url":"https://api.github.com/users/lavalamp/received_events","type":"User","site_admin":false},{"login":"nikhiljindal","id":10199099,"avatar_url":"https://avatars.githubusercontent.com/u/10199099?v=3","gravatar_id":"","url":"https://api.github.com/users/nikhiljindal","html_url":"https://github.com/nikhiljindal","followers_url":"https://api.github.com/users/nikhiljindal/followers","following_url":"https://api.github.com/users/nikhiljindal/following{/other_user}","gists_url":"https://api.github.com/users/nikhiljindal/gists{/gist_id}","starred_url":"https://api.github.com/users/nikhiljindal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikhiljindal/subscriptions","organizations_url":"https://api.github.com/users/nikhiljindal/orgs","repos_url":"https://api.github.com/users/nikhiljindal/repos","events_url":"https://api.github.com/users/nikhiljindal/events{/privacy}","received_events_url":"https://api.github.com/users/nikhiljindal/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/31468/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/1709b32b7ccb98303095c8114da9ff9451a1634d","head":{"label":"mbohlool:master","ref":"master","sha":"1709b32b7ccb98303095c8114da9ff9451a1634d","user":{"login":"mbohlool","id":1613024,"avatar_url":"https://avatars.githubusercontent.com/u/1613024?v=3","gravatar_id":"","url":"https://api.github.com/users/mbohlool","html_url":"https://github.com/mbohlool","followers_url":"https://api.github.com/users/mbohlool/followers","following_url":"https://api.github.com/users/mbohlool/following{/other_user}","gists_url":"https://api.github.com/users/mbohlool/gists{/gist_id}","starred_url":"https://api.github.com/users/mbohlool/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbohlool/subscriptions","organizations_url":"https://api.github.com/users/mbohlool/orgs","repos_url":"https://api.github.com/users/mbohlool/repos","events_url":"https://api.github.com/users/mbohlool/events{/privacy}","received_events_url":"https://api.github.com/users/mbohlool/received_events","type":"User","site_admin":false},"repo":{"id":58666689,"name":"kubernetes","full_name":"mbohlool/kubernetes","owner":{"login":"mbohlool","id":1613024,"avatar_url":"https://avatars.githubusercontent.com/u/1613024?v=3","gravatar_id":"","url":"https://api.github.com/users/mbohlool","html_url":"https://github.com/mbohlool","followers_url":"https://api.github.com/users/mbohlool/followers","following_url":"https://api.github.com/users/mbohlool/following{/other_user}","gists_url":"https://api.github.com/users/mbohlool/gists{/gist_id}","starred_url":"https://api.github.com/users/mbohlool/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbohlool/subscriptions","organizations_url":"https://api.github.com/users/mbohlool/orgs","repos_url":"https://api.github.com/users/mbohlool/repos","events_url":"https://api.github.com/users/mbohlool/events{/privacy}","received_events_url":"https://api.github.com/users/mbohlool/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mbohlool/kubernetes","description":"Container Cluster Manager from Google","fork":true,"url":"https://api.github.com/repos/mbohlool/kubernetes","forks_url":"https://api.github.com/repos/mbohlool/kubernetes/forks","keys_url":"https://api.github.com/repos/mbohlool/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mbohlool/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mbohlool/kubernetes/teams","hooks_url":"https://api.github.com/repos/mbohlool/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/mbohlool/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/mbohlool/kubernetes/events","assignees_url":"https://api.github.com/repos/mbohlool/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/mbohlool/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/mbohlool/kubernetes/tags","blobs_url":"https://api.github.com/repos/mbohlool/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mbohlool/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mbohlool/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/mbohlool/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mbohlool/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/mbohlool/kubernetes/languages","stargazers_url":"https://api.github.com/repos/mbohlool/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/mbohlool/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/mbohlool/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/mbohlool/kubernetes/subscription","commits_url":"https://api.github.com/repos/mbohlool/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/mbohlool/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/mbohlool/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/mbohlool/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/mbohlool/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/mbohlool/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mbohlool/kubernetes/merges","archive_url":"https://api.github.com/repos/mbohlool/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mbohlool/kubernetes/downloads","issues_url":"https://api.github.com/repos/mbohlool/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/mbohlool/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/mbohlool/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/mbohlool/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mbohlool/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/mbohlool/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/mbohlool/kubernetes/deployments","created_at":"2016-05-12T18:30:33Z","updated_at":"2016-05-12T18:30:48Z","pushed_at":"2016-09-02T03:43:00Z","git_url":"git://github.com/mbohlool/kubernetes.git","ssh_url":"git@github.com:mbohlool/kubernetes.git","clone_url":"https://github.com/mbohlool/kubernetes.git","svn_url":"https://github.com/mbohlool/kubernetes","homepage":"http://kubernetes.io","size":318502,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"9be47a2c5592aa1f55361ea20ee158672ff46ec8","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Production-Grade Container Scheduling and Management","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/kubernetes/kubernetes/deployments","created_at":"2014-06-06T22:56:04Z","updated_at":"2016-09-07T21:03:13Z","pushed_at":"2016-09-07T21:57:04Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":558436,"stargazers_count":16582,"watchers_count":16582,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":5349,"mirror_url":null,"open_issues_count":4418,"forks":5349,"open_issues":4418,"watchers":16582,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/31468"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/31468"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/31468/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/31468/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/1709b32b7ccb98303095c8114da9ff9451a1634d"}}}}
{"actor":{"display_login":"lavalamp"}}