{"action":"created","comment":{"url":"https://api.github.com/repos/hpcloud/fissile/pulls/comments/112037714","pull_request_review_id":33322348,"id":112037714,"diff_hunk":"@@ -842,3 +877,255 @@ roleLoop:\n \n \treturn nil\n }\n+\n+func (f *Fissile) validate(roleManifest *model.RoleManifest, opinions *model.Opinions) validation.ErrorList {\n+\tallErrs := validation.ErrorList{}\n+\n+\tbosh := f.collectPropertyDefaults()\n+\t// map: property.name -> (default.string -> [*job...]\n+\n+\tdark := model.FlatMap(opinions.Dark)\n+\tlight := model.FlatMap(opinions.Light)\n+\t// map[string]string\n+\n+\tproperties := manifestProperties(roleManifest)\n+\t// map[string]string\n+\n+\t// All properties must be defined in a BOSH release\n+\tallErrs = append(allErrs, validateBosh(\"role-manifest\",\n+\t\tproperties, bosh)...)\n+\n+\t// All light opinions must exists in a bosh release\n+\tallErrs = append(allErrs, validateBosh(\"light opinion\",\n+\t\tlight, bosh)...)\n+\n+\t// All dark opinions must exists in a bosh release\n+\tallErrs = append(allErrs, validateBosh(\"dark opinion\",\n+\t\tdark, bosh)...)\n+\n+\t// All dark opinions must be configured as templates\n+\tallErrs = append(allErrs, darkExposed(dark, properties)...)\n+\n+\t// No dark opinions must have defaults in light opinions\n+\tallErrs = append(allErrs, darkUnexposed(dark, light)...)\n+\n+\t// No duplicates must exist between role manifest and light\n+\t// opinions\n+\tallErrs = append(allErrs, checkOverrides(light, roleManifest)...)\n+\n+\t// All bosh properties in a release should have the same\n+\t// default across jobs -- WARNING only, not error\n+\tf.checkBoshDefaults(bosh)\n+\n+\t// All light opinions should differ from their defaults in the\n+\t// BOSH releases\n+\tallErrs = append(allErrs, f.checkLightDefaults(light, bosh)...)\n+\n+\t// \tallErrs = append(allErrs, XXX()...)\n+\n+\treturn allErrs\n+}\n+\n+func validateBosh(label string, properties map[string]string, bosh propertyDefaults) validation.ErrorList {\n+\t// All provided properties must be defined in a BOSH release\n+\tallErrs := validation.ErrorList{}\n+\n+\tfor property := range properties {\n+\t\t// Ignore specials (without the \"properties.\" prefix)\n+\t\tif !strings.HasPrefix(property, \"properties.\") {\n+\t\t\tcontinue\n+\t\t}\n+\t\tp := strings.TrimPrefix(property, \"properties.\")\n+\n+\t\tif _, ok := bosh[p]; !ok {\n+\t\t\tallErrs = append(allErrs, validation.NotFound(\n+\t\t\t\tfmt.Sprintf(\"%s '%s'\", label, p), \"In any BOSH release\"))\n+\t\t}\n+\t}\n+\n+\treturn allErrs\n+}\n+\n+func manifestProperties(roleManifest *model.RoleManifest) map[string]string {\n+\tproperties := make(map[string]string)\n+\n+\t// Per-role properties\n+\tfor _, role := range roleManifest.Roles {\n+\t\tfor property, template := range role.Configuration.Templates {\n+\t\t\tif _, ok := properties[property]; ok {\n+\t\t\t\tcontinue\n+\t\t\t}\n+\t\t\tproperties[property] = template\n+\t\t}\n+\t}\n+\n+\t// And the global properties\n+\tfor property, template := range roleManifest.Configuration.Templates {\n+\t\tif _, ok := properties[property]; ok {\n+\t\t\tcontinue\n+\t\t}\n+\t\tproperties[property] = template\n+\t}\n+\n+\treturn properties\n+}\n+\n+func darkExposed(dark map[string]string, properties map[string]string) validation.ErrorList {\n+\t// All dark opinions must be configured as templates\n+\tallErrs := validation.ErrorList{}\n+\n+\tfor property := range dark {\n+\t\tif _, ok := properties[property]; ok {\n+\t\t\tcontinue\n+\t\t}\n+\t\tallErrs = append(allErrs, validation.NotFound(\n+\t\t\tproperty, \"Dark opinion is missing template in role-manifest\"))\n+\t}\n+\n+\treturn allErrs\n+}\n+\n+func darkUnexposed(dark map[string]string, light map[string]string) validation.ErrorList {","path":"app/fissile.go","position":null,"original_position":178,"commit_id":"33e85568c4acea62386712b69809c319904f845e","original_commit_id":"ebbe2fed5f46de532e6cbb7166499beb0607fe3a","user":{"login":"andreas-kupries","id":577247,"avatar_url":"https://avatars3.githubusercontent.com/u/577247?v=3","gravatar_id":"","url":"https://api.github.com/users/andreas-kupries","html_url":"https://github.com/andreas-kupries","followers_url":"https://api.github.com/users/andreas-kupries/followers","following_url":"https://api.github.com/users/andreas-kupries/following{/other_user}","gists_url":"https://api.github.com/users/andreas-kupries/gists{/gist_id}","starred_url":"https://api.github.com/users/andreas-kupries/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreas-kupries/subscriptions","organizations_url":"https://api.github.com/users/andreas-kupries/orgs","repos_url":"https://api.github.com/users/andreas-kupries/repos","events_url":"https://api.github.com/users/andreas-kupries/events{/privacy}","received_events_url":"https://api.github.com/users/andreas-kupries/received_events","type":"User","site_admin":false},"body":"Done with commit 33e85568c4acea62386712b69809c319904f845e","created_at":"2017-04-18T19:04:27Z","updated_at":"2017-04-18T19:04:27Z","html_url":"https://github.com/hpcloud/fissile/pull/217#discussion_r112037714","pull_request_url":"https://api.github.com/repos/hpcloud/fissile/pulls/217","_links":{"self":{"href":"https://api.github.com/repos/hpcloud/fissile/pulls/comments/112037714"},"html":{"href":"https://github.com/hpcloud/fissile/pull/217#discussion_r112037714"},"pull_request":{"href":"https://api.github.com/repos/hpcloud/fissile/pulls/217"}}},"pull_request":{"url":"https://api.github.com/repos/hpcloud/fissile/pulls/217","id":115840248,"html_url":"https://github.com/hpcloud/fissile/pull/217","diff_url":"https://github.com/hpcloud/fissile/pull/217.diff","patch_url":"https://github.com/hpcloud/fissile/pull/217.patch","issue_url":"https://api.github.com/repos/hpcloud/fissile/issues/217","number":217,"state":"open","locked":false,"title":"More manifest validation","user":{"login":"andreas-kupries","id":577247,"avatar_url":"https://avatars3.githubusercontent.com/u/577247?v=3","gravatar_id":"","url":"https://api.github.com/users/andreas-kupries","html_url":"https://github.com/andreas-kupries","followers_url":"https://api.github.com/users/andreas-kupries/followers","following_url":"https://api.github.com/users/andreas-kupries/following{/other_user}","gists_url":"https://api.github.com/users/andreas-kupries/gists{/gist_id}","starred_url":"https://api.github.com/users/andreas-kupries/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreas-kupries/subscriptions","organizations_url":"https://api.github.com/users/andreas-kupries/orgs","repos_url":"https://api.github.com/users/andreas-kupries/repos","events_url":"https://api.github.com/users/andreas-kupries/events{/privacy}","received_events_url":"https://api.github.com/users/andreas-kupries/received_events","type":"User","site_admin":false},"body":"Details @ https://trello.com/c/FFT7VDxo/12-5-implement-validation-for-rm-opinions-vars-etc-in-fissile\r\nIncluding open issues.\r\n\r\nCopied in to get around closed-ness:\r\n\r\nThe new fissile reports on the current HCF (after fixing tcp --> TCP in two port specs):\r\nconfiguration.variables: Not found: \"No templates using 'HCF_LOG_PROTOCOL'\" configuration.variables: Not found: \"No templates using 'HCF_LOG_HOST'\" configuration.variables: Not found: \"No templates using 'HCF_LOG_PORT'\"\r\nThis requires discussion. We are now running into special variables used in scripts, but not templates, and similar things.\r\n\r\nWe could extend the manifest with additional information to declare the specials and prevent them from generating errors. That should be easy.\r\nWe could also try to locate the scripts referenced by the manifest, and grep them for variables. That should be difficult. Possibly brittle. Possibly more accurate than the manual maintenance required by the previous solution.\r\n\r\nAnd from code comments:\r\n// It reports all variables which are not used by at least one template.\r\n// ATTENTION: This will mis-report any variables which are used only\r\n// in scripts, but not in templates.\r\n\r\n\r\n\r\n","created_at":"2017-04-13T20:50:18Z","updated_at":"2017-04-18T19:04:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8118a820104ba0fe079e5ecfd53f7854c3ce87ec","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/hpcloud/fissile/pulls/217/commits","review_comments_url":"https://api.github.com/repos/hpcloud/fissile/pulls/217/comments","review_comment_url":"https://api.github.com/repos/hpcloud/fissile/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hpcloud/fissile/issues/217/comments","statuses_url":"https://api.github.com/repos/hpcloud/fissile/statuses/33e85568c4acea62386712b69809c319904f845e","head":{"label":"hpcloud:aku-more-manifest-validation","ref":"aku-more-manifest-validation","sha":"33e85568c4acea62386712b69809c319904f845e","user":{"login":"hpcloud","id":366390,"avatar_url":"https://avatars3.githubusercontent.com/u/366390?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcloud","html_url":"https://github.com/hpcloud","followers_url":"https://api.github.com/users/hpcloud/followers","following_url":"https://api.github.com/users/hpcloud/following{/other_user}","gists_url":"https://api.github.com/users/hpcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcloud/subscriptions","organizations_url":"https://api.github.com/users/hpcloud/orgs","repos_url":"https://api.github.com/users/hpcloud/repos","events_url":"https://api.github.com/users/hpcloud/events{/privacy}","received_events_url":"https://api.github.com/users/hpcloud/received_events","type":"Organization","site_admin":false},"repo":{"id":42498148,"name":"fissile","full_name":"hpcloud/fissile","owner":{"login":"hpcloud","id":366390,"avatar_url":"https://avatars3.githubusercontent.com/u/366390?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcloud","html_url":"https://github.com/hpcloud","followers_url":"https://api.github.com/users/hpcloud/followers","following_url":"https://api.github.com/users/hpcloud/following{/other_user}","gists_url":"https://api.github.com/users/hpcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcloud/subscriptions","organizations_url":"https://api.github.com/users/hpcloud/orgs","repos_url":"https://api.github.com/users/hpcloud/repos","events_url":"https://api.github.com/users/hpcloud/events{/privacy}","received_events_url":"https://api.github.com/users/hpcloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/hpcloud/fissile","description":"Turn a BOSH release into Docker images / files","fork":false,"url":"https://api.github.com/repos/hpcloud/fissile","forks_url":"https://api.github.com/repos/hpcloud/fissile/forks","keys_url":"https://api.github.com/repos/hpcloud/fissile/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hpcloud/fissile/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hpcloud/fissile/teams","hooks_url":"https://api.github.com/repos/hpcloud/fissile/hooks","issue_events_url":"https://api.github.com/repos/hpcloud/fissile/issues/events{/number}","events_url":"https://api.github.com/repos/hpcloud/fissile/events","assignees_url":"https://api.github.com/repos/hpcloud/fissile/assignees{/user}","branches_url":"https://api.github.com/repos/hpcloud/fissile/branches{/branch}","tags_url":"https://api.github.com/repos/hpcloud/fissile/tags","blobs_url":"https://api.github.com/repos/hpcloud/fissile/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hpcloud/fissile/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hpcloud/fissile/git/refs{/sha}","trees_url":"https://api.github.com/repos/hpcloud/fissile/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hpcloud/fissile/statuses/{sha}","languages_url":"https://api.github.com/repos/hpcloud/fissile/languages","stargazers_url":"https://api.github.com/repos/hpcloud/fissile/stargazers","contributors_url":"https://api.github.com/repos/hpcloud/fissile/contributors","subscribers_url":"https://api.github.com/repos/hpcloud/fissile/subscribers","subscription_url":"https://api.github.com/repos/hpcloud/fissile/subscription","commits_url":"https://api.github.com/repos/hpcloud/fissile/commits{/sha}","git_commits_url":"https://api.github.com/repos/hpcloud/fissile/git/commits{/sha}","comments_url":"https://api.github.com/repos/hpcloud/fissile/comments{/number}","issue_comment_url":"https://api.github.com/repos/hpcloud/fissile/issues/comments{/number}","contents_url":"https://api.github.com/repos/hpcloud/fissile/contents/{+path}","compare_url":"https://api.github.com/repos/hpcloud/fissile/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hpcloud/fissile/merges","archive_url":"https://api.github.com/repos/hpcloud/fissile/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hpcloud/fissile/downloads","issues_url":"https://api.github.com/repos/hpcloud/fissile/issues{/number}","pulls_url":"https://api.github.com/repos/hpcloud/fissile/pulls{/number}","milestones_url":"https://api.github.com/repos/hpcloud/fissile/milestones{/number}","notifications_url":"https://api.github.com/repos/hpcloud/fissile/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hpcloud/fissile/labels{/name}","releases_url":"https://api.github.com/repos/hpcloud/fissile/releases{/id}","deployments_url":"https://api.github.com/repos/hpcloud/fissile/deployments","created_at":"2015-09-15T05:51:21Z","updated_at":"2017-04-13T08:47:37Z","pushed_at":"2017-04-18T19:02:56Z","git_url":"git://github.com/hpcloud/fissile.git","ssh_url":"git@github.com:hpcloud/fissile.git","clone_url":"https://github.com/hpcloud/fissile.git","svn_url":"https://github.com/hpcloud/fissile","homepage":"","size":61610,"stargazers_count":18,"watchers_count":18,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":7,"forks":9,"open_issues":7,"watchers":18,"default_branch":"master"}},"base":{"label":"hpcloud:master","ref":"master","sha":"e24f4e664f51d55e7be31aad22ff75e0eb7f2f40","user":{"login":"hpcloud","id":366390,"avatar_url":"https://avatars3.githubusercontent.com/u/366390?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcloud","html_url":"https://github.com/hpcloud","followers_url":"https://api.github.com/users/hpcloud/followers","following_url":"https://api.github.com/users/hpcloud/following{/other_user}","gists_url":"https://api.github.com/users/hpcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcloud/subscriptions","organizations_url":"https://api.github.com/users/hpcloud/orgs","repos_url":"https://api.github.com/users/hpcloud/repos","events_url":"https://api.github.com/users/hpcloud/events{/privacy}","received_events_url":"https://api.github.com/users/hpcloud/received_events","type":"Organization","site_admin":false},"repo":{"id":42498148,"name":"fissile","full_name":"hpcloud/fissile","owner":{"login":"hpcloud","id":366390,"avatar_url":"https://avatars3.githubusercontent.com/u/366390?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcloud","html_url":"https://github.com/hpcloud","followers_url":"https://api.github.com/users/hpcloud/followers","following_url":"https://api.github.com/users/hpcloud/following{/other_user}","gists_url":"https://api.github.com/users/hpcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcloud/subscriptions","organizations_url":"https://api.github.com/users/hpcloud/orgs","repos_url":"https://api.github.com/users/hpcloud/repos","events_url":"https://api.github.com/users/hpcloud/events{/privacy}","received_events_url":"https://api.github.com/users/hpcloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/hpcloud/fissile","description":"Turn a BOSH release into Docker images / files","fork":false,"url":"https://api.github.com/repos/hpcloud/fissile","forks_url":"https://api.github.com/repos/hpcloud/fissile/forks","keys_url":"https://api.github.com/repos/hpcloud/fissile/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hpcloud/fissile/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hpcloud/fissile/teams","hooks_url":"https://api.github.com/repos/hpcloud/fissile/hooks","issue_events_url":"https://api.github.com/repos/hpcloud/fissile/issues/events{/number}","events_url":"https://api.github.com/repos/hpcloud/fissile/events","assignees_url":"https://api.github.com/repos/hpcloud/fissile/assignees{/user}","branches_url":"https://api.github.com/repos/hpcloud/fissile/branches{/branch}","tags_url":"https://api.github.com/repos/hpcloud/fissile/tags","blobs_url":"https://api.github.com/repos/hpcloud/fissile/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hpcloud/fissile/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hpcloud/fissile/git/refs{/sha}","trees_url":"https://api.github.com/repos/hpcloud/fissile/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hpcloud/fissile/statuses/{sha}","languages_url":"https://api.github.com/repos/hpcloud/fissile/languages","stargazers_url":"https://api.github.com/repos/hpcloud/fissile/stargazers","contributors_url":"https://api.github.com/repos/hpcloud/fissile/contributors","subscribers_url":"https://api.github.com/repos/hpcloud/fissile/subscribers","subscription_url":"https://api.github.com/repos/hpcloud/fissile/subscription","commits_url":"https://api.github.com/repos/hpcloud/fissile/commits{/sha}","git_commits_url":"https://api.github.com/repos/hpcloud/fissile/git/commits{/sha}","comments_url":"https://api.github.com/repos/hpcloud/fissile/comments{/number}","issue_comment_url":"https://api.github.com/repos/hpcloud/fissile/issues/comments{/number}","contents_url":"https://api.github.com/repos/hpcloud/fissile/contents/{+path}","compare_url":"https://api.github.com/repos/hpcloud/fissile/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hpcloud/fissile/merges","archive_url":"https://api.github.com/repos/hpcloud/fissile/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hpcloud/fissile/downloads","issues_url":"https://api.github.com/repos/hpcloud/fissile/issues{/number}","pulls_url":"https://api.github.com/repos/hpcloud/fissile/pulls{/number}","milestones_url":"https://api.github.com/repos/hpcloud/fissile/milestones{/number}","notifications_url":"https://api.github.com/repos/hpcloud/fissile/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hpcloud/fissile/labels{/name}","releases_url":"https://api.github.com/repos/hpcloud/fissile/releases{/id}","deployments_url":"https://api.github.com/repos/hpcloud/fissile/deployments","created_at":"2015-09-15T05:51:21Z","updated_at":"2017-04-13T08:47:37Z","pushed_at":"2017-04-18T19:02:56Z","git_url":"git://github.com/hpcloud/fissile.git","ssh_url":"git@github.com:hpcloud/fissile.git","clone_url":"https://github.com/hpcloud/fissile.git","svn_url":"https://github.com/hpcloud/fissile","homepage":"","size":61610,"stargazers_count":18,"watchers_count":18,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":7,"forks":9,"open_issues":7,"watchers":18,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hpcloud/fissile/pulls/217"},"html":{"href":"https://github.com/hpcloud/fissile/pull/217"},"issue":{"href":"https://api.github.com/repos/hpcloud/fissile/issues/217"},"comments":{"href":"https://api.github.com/repos/hpcloud/fissile/issues/217/comments"},"review_comments":{"href":"https://api.github.com/repos/hpcloud/fissile/pulls/217/comments"},"review_comment":{"href":"https://api.github.com/repos/hpcloud/fissile/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hpcloud/fissile/pulls/217/commits"},"statuses":{"href":"https://api.github.com/repos/hpcloud/fissile/statuses/33e85568c4acea62386712b69809c319904f845e"}}}}
{"actor":{"display_login":"andreas-kupries"}}