{"action":"created","comment":{"url":"https://api.github.com/repos/kiali/kiali/pulls/comments/185746322","pull_request_review_id":117195956,"id":185746322,"diff_hunk":"@@ -0,0 +1,58 @@\n+package checkers\n+\n+import (\n+\t\"github.com/kiali/kiali/kubernetes\"\n+\t\"github.com/kiali/kiali/services/business/checkers/route_rules\"\n+\t\"github.com/kiali/kiali/services/models\"\n+)\n+\n+const objectType = \"routerule\"\n+\n+type Checker interface {\n+\tCheck() ([]*models.IstioCheck, bool)\n+}\n+\n+type RouteRuleChecker struct {\n+\tRouteRules []kubernetes.IstioObject\n+}\n+\n+func (in RouteRuleChecker) Check() *models.IstioValidations {\n+\tobjectValidations := models.IstioValidations{}\n+\n+\tobjectValidations = objectValidations.MergeValidations(in.runIndividualChecks())\n+\tobjectValidations = objectValidations.MergeValidations(in.runGroupChecks())\n+\n+\treturn &objectValidations\n+}\n+\n+func (in RouteRuleChecker) runIndividualChecks() *models.IstioValidations {\n+\tvalidations := models.IstioValidations{}\n+\n+\tfor _, routeRule := range in.RouteRules {\n+\t\tvalid := true\n+\t\truleName := routeRule.GetObjectMeta().Name\n+\t\tistioValidation := &models.IstioValidation{Name: ruleName, ObjectType: objectType}\n+\n+\t\tfor _, checker := range in.enabledCheckersFor(routeRule) {\n+\t\t\tchecks, validChecker := checker.Check()\n+\t\t\tistioValidation.Checks = append(istioValidation.Checks, checks...)\n+\t\t\tvalid = valid && validChecker\n+\t\t}\n+\n+\t\tistioValidation.Valid = valid\n+\t\tvalidations[ruleName] = istioValidation\n+\t}\n+\n+\treturn &validations\n+}\n+\n+func (in *RouteRuleChecker) runGroupChecks() *models.IstioValidations {","path":"services/business/checkers/route_rule_checker.go","position":49,"original_position":49,"commit_id":"c5637173ebd1428a8961ded06ed32be1d9805543","original_commit_id":"c5637173ebd1428a8961ded06ed32be1d9805543","user":{"login":"xeviknal","id":613814,"avatar_url":"https://avatars2.githubusercontent.com/u/613814?v=4","gravatar_id":"","url":"https://api.github.com/users/xeviknal","html_url":"https://github.com/xeviknal","followers_url":"https://api.github.com/users/xeviknal/followers","following_url":"https://api.github.com/users/xeviknal/following{/other_user}","gists_url":"https://api.github.com/users/xeviknal/gists{/gist_id}","starred_url":"https://api.github.com/users/xeviknal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xeviknal/subscriptions","organizations_url":"https://api.github.com/users/xeviknal/orgs","repos_url":"https://api.github.com/users/xeviknal/repos","events_url":"https://api.github.com/users/xeviknal/events{/privacy}","received_events_url":"https://api.github.com/users/xeviknal/received_events","type":"User","site_admin":false},"body":"I just divided the checks in two groups:\r\n1. Individual object checks: checking the integrity of that specific object. Not considering how the other co-living  objects modifies its integrity (e.g. validate precedence values - positive number)\r\n2. Object group checks: checking the integrity among a collection of istio objects. Considering the behavior of the whole group. (e.g. route rule with precedence 0 has 100% of the traffic weight, so route rule with precedence 1 has no effect)\r\n","created_at":"2018-05-03T09:49:40Z","updated_at":"2018-05-03T09:49:40Z","html_url":"https://github.com/kiali/kiali/pull/180#discussion_r185746322","pull_request_url":"https://api.github.com/repos/kiali/kiali/pulls/180","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/kiali/kiali/pulls/comments/185746322"},"html":{"href":"https://github.com/kiali/kiali/pull/180#discussion_r185746322"},"pull_request":{"href":"https://api.github.com/repos/kiali/kiali/pulls/180"}},"in_reply_to_id":185725311},"pull_request":{"url":"https://api.github.com/repos/kiali/kiali/pulls/180","id":184921837,"html_url":"https://github.com/kiali/kiali/pull/180","diff_url":"https://github.com/kiali/kiali/pull/180.diff","patch_url":"https://github.com/kiali/kiali/pull/180.patch","issue_url":"https://api.github.com/repos/kiali/kiali/issues/180","number":180,"state":"open","locked":false,"title":"Kiali 556 - Add configuration checks for Istio Objects","user":{"login":"xeviknal","id":613814,"avatar_url":"https://avatars2.githubusercontent.com/u/613814?v=4","gravatar_id":"","url":"https://api.github.com/users/xeviknal","html_url":"https://github.com/xeviknal","followers_url":"https://api.github.com/users/xeviknal/followers","following_url":"https://api.github.com/users/xeviknal/following{/other_user}","gists_url":"https://api.github.com/users/xeviknal/gists{/gist_id}","starred_url":"https://api.github.com/users/xeviknal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xeviknal/subscriptions","organizations_url":"https://api.github.com/users/xeviknal/orgs","repos_url":"https://api.github.com/users/xeviknal/repos","events_url":"https://api.github.com/users/xeviknal/events{/privacy}","received_events_url":"https://api.github.com/users/xeviknal/received_events","type":"User","site_admin":false},"body":"# Goal\r\nThis provides to KIALI a system prepared to run checks for all desired Istio Objects (route rules, destination policies, virtual services and destination rules).\r\n\r\nRight now, in this PR, route rule weight and precedence validations are added. However, this system allow us to add as many validations as wanted (following SOLID principles).\r\n\r\nPR related to [KIALI-556](https://issues.jboss.org/browse/KIALI-556) (and parcially documented in [KIALI-555](https://issues.jboss.org/browse/KIALI-555)).\r\n\r\n## Output\r\n\r\n![endpoint-both-valid-invalid](https://user-images.githubusercontent.com/613814/39537113-e4aa7e0e-4e38-11e8-9d1d-4f693aaf79c0.png)\r\n\r\n### IstioValidation\r\nFor each IstioObject, we have an IstioValidation which aggregate all checks run for it.\r\n\r\nAn IstioValidation has:\r\n- name: name of the istio object\r\n- object_type: routerule, destinationpolicy,...\r\n- valid: bool - true means that there are at least one check that returns an error (warnings are counted as valid)\r\n- checks: array of IstioCheck - each check is a notification (i.e.: error, warning, improvement) for that istio object.\r\n\r\n### IstioCheck\r\nAn IstioCheck is a configuration error, warning or improvement that one of the checkers has detected in a given Istio Object. (e.g. routing traffic to non-existant service).\r\n\r\nAn IstioCheck has:\r\n- message: descriptive message of the error found.\r\n- severity: type of message (error, warning, improvement)\r\n- path: key that shows where exactly the error is found in the yaml.\r\n\r\n#### Path\r\nGiven the following yaml, with an error on precedence value:\r\n\r\n```yaml\r\napiVersion: config.istio.io/v1alpha2\r\nkind: RouteRule\r\nmetadata:\r\n  name: reviews-default\r\nspec:\r\n  destination:\r\n    name: reviews\r\n  precedence: -2\r\n  route:\r\n  - labels:\r\n      version: v2\r\n    weight: 55\r\n  - labels:\r\n      version: v3\r\n    weight: 45\r\n```\r\n\r\nPath give a precise method to point where the error is. For the previous example, path value would be `spec/precedence/-2` (precedence has to be a positive number).\r\n\r\n## Architecture\r\n\r\n### ObjectChecker\r\nAn Object checker is a component responsible of running all the checks registered for an specific Istio Object.\r\nFor example, the RouteRuleChecker runs checks for weight validations within route balancing (sum of weights must be 100) and for precedence statement (checking that is always a positive number).\r\n\r\nCheck an ObjectChecker out [here](https://github.com/kiali/kiali/pull/180/files#diff-14de00b9c8bae60d021a351f4d1070fb).\r\n\r\n### Checker\r\nA Checker is a specific validation run for a Istio Object. One checker is responsible of checking one specific aspect of that Istio object. For example, check precedence validity (number and positive).\r\n\r\nCheck a Checker object out [here](https://github.com/kiali/kiali/pull/180/files#diff-bc9f505892e59eb9a6171329d40c8c32)\r\n\r\nThere will be one Object checker file for each Istio Object.\r\n\r\n### Service\r\nOn top of it, we have a service/business object responsible of connecting the request handler with this validation system.\r\nService is called [IstioValidationService](https://github.com/kiali/kiali/pull/180/files#diff-e5fee97773f0c6b94aa993b34ca6d286).\r\n\r\n\r\nBest practices guides followed:\r\n- https://talks.golang.org/2014/go4gophers.slide\r\n- https://talks.golang.org/2013/bestpractices.slide","created_at":"2018-04-30T10:21:00Z","updated_at":"2018-05-03T09:49:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ff480da945e403a8ff566dc2b17bcfedf597f09a","assignee":null,"assignees":[],"requested_reviewers":[{"login":"aljesusg","id":3019213,"avatar_url":"https://avatars2.githubusercontent.com/u/3019213?v=4","gravatar_id":"","url":"https://api.github.com/users/aljesusg","html_url":"https://github.com/aljesusg","followers_url":"https://api.github.com/users/aljesusg/followers","following_url":"https://api.github.com/users/aljesusg/following{/other_user}","gists_url":"https://api.github.com/users/aljesusg/gists{/gist_id}","starred_url":"https://api.github.com/users/aljesusg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aljesusg/subscriptions","organizations_url":"https://api.github.com/users/aljesusg/orgs","repos_url":"https://api.github.com/users/aljesusg/repos","events_url":"https://api.github.com/users/aljesusg/events{/privacy}","received_events_url":"https://api.github.com/users/aljesusg/received_events","type":"User","site_admin":false},{"login":"abonas","id":6277245,"avatar_url":"https://avatars2.githubusercontent.com/u/6277245?v=4","gravatar_id":"","url":"https://api.github.com/users/abonas","html_url":"https://github.com/abonas","followers_url":"https://api.github.com/users/abonas/followers","following_url":"https://api.github.com/users/abonas/following{/other_user}","gists_url":"https://api.github.com/users/abonas/gists{/gist_id}","starred_url":"https://api.github.com/users/abonas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/abonas/subscriptions","organizations_url":"https://api.github.com/users/abonas/orgs","repos_url":"https://api.github.com/users/abonas/repos","events_url":"https://api.github.com/users/abonas/events{/privacy}","received_events_url":"https://api.github.com/users/abonas/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/kiali/kiali/pulls/180/commits","review_comments_url":"https://api.github.com/repos/kiali/kiali/pulls/180/comments","review_comment_url":"https://api.github.com/repos/kiali/kiali/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kiali/kiali/issues/180/comments","statuses_url":"https://api.github.com/repos/kiali/kiali/statuses/c5637173ebd1428a8961ded06ed32be1d9805543","head":{"label":"xeviknal:KIALI-556","ref":"KIALI-556","sha":"c5637173ebd1428a8961ded06ed32be1d9805543","user":{"login":"xeviknal","id":613814,"avatar_url":"https://avatars2.githubusercontent.com/u/613814?v=4","gravatar_id":"","url":"https://api.github.com/users/xeviknal","html_url":"https://github.com/xeviknal","followers_url":"https://api.github.com/users/xeviknal/followers","following_url":"https://api.github.com/users/xeviknal/following{/other_user}","gists_url":"https://api.github.com/users/xeviknal/gists{/gist_id}","starred_url":"https://api.github.com/users/xeviknal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xeviknal/subscriptions","organizations_url":"https://api.github.com/users/xeviknal/orgs","repos_url":"https://api.github.com/users/xeviknal/repos","events_url":"https://api.github.com/users/xeviknal/events{/privacy}","received_events_url":"https://api.github.com/users/xeviknal/received_events","type":"User","site_admin":false},"repo":{"id":120455008,"name":"swscore","full_name":"xeviknal/swscore","owner":{"login":"xeviknal","id":613814,"avatar_url":"https://avatars2.githubusercontent.com/u/613814?v=4","gravatar_id":"","url":"https://api.github.com/users/xeviknal","html_url":"https://github.com/xeviknal","followers_url":"https://api.github.com/users/xeviknal/followers","following_url":"https://api.github.com/users/xeviknal/following{/other_user}","gists_url":"https://api.github.com/users/xeviknal/gists{/gist_id}","starred_url":"https://api.github.com/users/xeviknal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xeviknal/subscriptions","organizations_url":"https://api.github.com/users/xeviknal/orgs","repos_url":"https://api.github.com/users/xeviknal/repos","events_url":"https://api.github.com/users/xeviknal/events{/privacy}","received_events_url":"https://api.github.com/users/xeviknal/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/xeviknal/swscore","description":null,"fork":true,"url":"https://api.github.com/repos/xeviknal/swscore","forks_url":"https://api.github.com/repos/xeviknal/swscore/forks","keys_url":"https://api.github.com/repos/xeviknal/swscore/keys{/key_id}","collaborators_url":"https://api.github.com/repos/xeviknal/swscore/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/xeviknal/swscore/teams","hooks_url":"https://api.github.com/repos/xeviknal/swscore/hooks","issue_events_url":"https://api.github.com/repos/xeviknal/swscore/issues/events{/number}","events_url":"https://api.github.com/repos/xeviknal/swscore/events","assignees_url":"https://api.github.com/repos/xeviknal/swscore/assignees{/user}","branches_url":"https://api.github.com/repos/xeviknal/swscore/branches{/branch}","tags_url":"https://api.github.com/repos/xeviknal/swscore/tags","blobs_url":"https://api.github.com/repos/xeviknal/swscore/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/xeviknal/swscore/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/xeviknal/swscore/git/refs{/sha}","trees_url":"https://api.github.com/repos/xeviknal/swscore/git/trees{/sha}","statuses_url":"https://api.github.com/repos/xeviknal/swscore/statuses/{sha}","languages_url":"https://api.github.com/repos/xeviknal/swscore/languages","stargazers_url":"https://api.github.com/repos/xeviknal/swscore/stargazers","contributors_url":"https://api.github.com/repos/xeviknal/swscore/contributors","subscribers_url":"https://api.github.com/repos/xeviknal/swscore/subscribers","subscription_url":"https://api.github.com/repos/xeviknal/swscore/subscription","commits_url":"https://api.github.com/repos/xeviknal/swscore/commits{/sha}","git_commits_url":"https://api.github.com/repos/xeviknal/swscore/git/commits{/sha}","comments_url":"https://api.github.com/repos/xeviknal/swscore/comments{/number}","issue_comment_url":"https://api.github.com/repos/xeviknal/swscore/issues/comments{/number}","contents_url":"https://api.github.com/repos/xeviknal/swscore/contents/{+path}","compare_url":"https://api.github.com/repos/xeviknal/swscore/compare/{base}...{head}","merges_url":"https://api.github.com/repos/xeviknal/swscore/merges","archive_url":"https://api.github.com/repos/xeviknal/swscore/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/xeviknal/swscore/downloads","issues_url":"https://api.github.com/repos/xeviknal/swscore/issues{/number}","pulls_url":"https://api.github.com/repos/xeviknal/swscore/pulls{/number}","milestones_url":"https://api.github.com/repos/xeviknal/swscore/milestones{/number}","notifications_url":"https://api.github.com/repos/xeviknal/swscore/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/xeviknal/swscore/labels{/name}","releases_url":"https://api.github.com/repos/xeviknal/swscore/releases{/id}","deployments_url":"https://api.github.com/repos/xeviknal/swscore/deployments","created_at":"2018-02-06T12:44:52Z","updated_at":"2018-04-05T10:05:23Z","pushed_at":"2018-05-02T15:33:12Z","git_url":"git://github.com/xeviknal/swscore.git","ssh_url":"git@github.com:xeviknal/swscore.git","clone_url":"https://github.com/xeviknal/swscore.git","svn_url":"https://github.com/xeviknal/swscore","homepage":null,"size":10625,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kiali:master","ref":"master","sha":"5332dee0b2ea70d77128e313bc34d9747e4e25ab","user":{"login":"kiali","id":36001875,"avatar_url":"https://avatars2.githubusercontent.com/u/36001875?v=4","gravatar_id":"","url":"https://api.github.com/users/kiali","html_url":"https://github.com/kiali","followers_url":"https://api.github.com/users/kiali/followers","following_url":"https://api.github.com/users/kiali/following{/other_user}","gists_url":"https://api.github.com/users/kiali/gists{/gist_id}","starred_url":"https://api.github.com/users/kiali/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kiali/subscriptions","organizations_url":"https://api.github.com/users/kiali/orgs","repos_url":"https://api.github.com/users/kiali/repos","events_url":"https://api.github.com/users/kiali/events{/privacy}","received_events_url":"https://api.github.com/users/kiali/received_events","type":"Organization","site_admin":false},"repo":{"id":120181748,"name":"kiali","full_name":"kiali/kiali","owner":{"login":"kiali","id":36001875,"avatar_url":"https://avatars2.githubusercontent.com/u/36001875?v=4","gravatar_id":"","url":"https://api.github.com/users/kiali","html_url":"https://github.com/kiali","followers_url":"https://api.github.com/users/kiali/followers","following_url":"https://api.github.com/users/kiali/following{/other_user}","gists_url":"https://api.github.com/users/kiali/gists{/gist_id}","starred_url":"https://api.github.com/users/kiali/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kiali/subscriptions","organizations_url":"https://api.github.com/users/kiali/orgs","repos_url":"https://api.github.com/users/kiali/repos","events_url":"https://api.github.com/users/kiali/events{/privacy}","received_events_url":"https://api.github.com/users/kiali/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kiali/kiali","description":"Kiali project","fork":false,"url":"https://api.github.com/repos/kiali/kiali","forks_url":"https://api.github.com/repos/kiali/kiali/forks","keys_url":"https://api.github.com/repos/kiali/kiali/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kiali/kiali/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kiali/kiali/teams","hooks_url":"https://api.github.com/repos/kiali/kiali/hooks","issue_events_url":"https://api.github.com/repos/kiali/kiali/issues/events{/number}","events_url":"https://api.github.com/repos/kiali/kiali/events","assignees_url":"https://api.github.com/repos/kiali/kiali/assignees{/user}","branches_url":"https://api.github.com/repos/kiali/kiali/branches{/branch}","tags_url":"https://api.github.com/repos/kiali/kiali/tags","blobs_url":"https://api.github.com/repos/kiali/kiali/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kiali/kiali/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kiali/kiali/git/refs{/sha}","trees_url":"https://api.github.com/repos/kiali/kiali/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kiali/kiali/statuses/{sha}","languages_url":"https://api.github.com/repos/kiali/kiali/languages","stargazers_url":"https://api.github.com/repos/kiali/kiali/stargazers","contributors_url":"https://api.github.com/repos/kiali/kiali/contributors","subscribers_url":"https://api.github.com/repos/kiali/kiali/subscribers","subscription_url":"https://api.github.com/repos/kiali/kiali/subscription","commits_url":"https://api.github.com/repos/kiali/kiali/commits{/sha}","git_commits_url":"https://api.github.com/repos/kiali/kiali/git/commits{/sha}","comments_url":"https://api.github.com/repos/kiali/kiali/comments{/number}","issue_comment_url":"https://api.github.com/repos/kiali/kiali/issues/comments{/number}","contents_url":"https://api.github.com/repos/kiali/kiali/contents/{+path}","compare_url":"https://api.github.com/repos/kiali/kiali/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kiali/kiali/merges","archive_url":"https://api.github.com/repos/kiali/kiali/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kiali/kiali/downloads","issues_url":"https://api.github.com/repos/kiali/kiali/issues{/number}","pulls_url":"https://api.github.com/repos/kiali/kiali/pulls{/number}","milestones_url":"https://api.github.com/repos/kiali/kiali/milestones{/number}","notifications_url":"https://api.github.com/repos/kiali/kiali/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kiali/kiali/labels{/name}","releases_url":"https://api.github.com/repos/kiali/kiali/releases{/id}","deployments_url":"https://api.github.com/repos/kiali/kiali/deployments","created_at":"2018-02-04T12:11:57Z","updated_at":"2018-04-30T14:45:07Z","pushed_at":"2018-05-03T08:26:29Z","git_url":"git://github.com/kiali/kiali.git","ssh_url":"git@github.com:kiali/kiali.git","clone_url":"https://github.com/kiali/kiali.git","svn_url":"https://github.com/kiali/kiali","homepage":"","size":10610,"stargazers_count":11,"watchers_count":11,"language":"Go","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":20,"mirror_url":null,"archived":false,"open_issues_count":7,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":20,"open_issues":7,"watchers":11,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kiali/kiali/pulls/180"},"html":{"href":"https://github.com/kiali/kiali/pull/180"},"issue":{"href":"https://api.github.com/repos/kiali/kiali/issues/180"},"comments":{"href":"https://api.github.com/repos/kiali/kiali/issues/180/comments"},"review_comments":{"href":"https://api.github.com/repos/kiali/kiali/pulls/180/comments"},"review_comment":{"href":"https://api.github.com/repos/kiali/kiali/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kiali/kiali/pulls/180/commits"},"statuses":{"href":"https://api.github.com/repos/kiali/kiali/statuses/c5637173ebd1428a8961ded06ed32be1d9805543"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"xeviknal"}}