{"action":"created","comment":{"url":"https://api.github.com/repos/heptio/contour/pulls/comments/178759906","pull_request_review_id":108869628,"id":178759906,"diff_hunk":"@@ -0,0 +1,398 @@\n+# Executive Summary\n+\n+This document describes the design of a new CRD designed to replace the v1beta1.Ingress Kubernetes object.\n+This new CRD will be integrated into Contour 0.5/0.6.\n+Contour will continue to support the current v1beta1.Ingress object for as long as it is supported in upstream Kubernetes.\n+\n+# Goals\n+\n+- Support multi tennant clusters with the ability to limit the management of routes to specific virtualhosts.\n+- Support the ability to delegate the configuration of some or all of the routes for a virtual host to another namespace\n+- Create a clear separation between \"singleton\" configure items--those that relate to the virtual host--and the \"set\" configuration items--routes on said virtual host.\n+\n+# Non-goals\n+\n+- Support ingress objects outside the current cluster\n+- IP in IP or GRE tunneling between custers with discontinious or overlapping IP ranges.\n+- Support non HTTP/HTTPS traffic ingress (ie, no UDP, no MongoDB, no TCP passthrough). We just do HTTP/HTTPS ingress.\n+- Deprecate Contours support for v1beta1.Ingress.\n+\n+# Background\n+\n+The ingress object was added to kubernetes in 1.2 as a way of describing properties of a cluster wide reverse HTTP proxy.\n+Since that time the ingress object has not progressed beyond the beta stage, and its stagnation inspired a cambrian explosion of annotations to express missing properties of http routing.\n+\n+# High-Level Design\n+\n+At a high level, this document proposes modeling ingress configuation as a graph of documents throughout a Kubernetes API server which when taken together form a directed acyclic graph (DAG) of the configuration for virtual hosts and their constituent routes.\n+\n+## Delegation\n+\n+The working model for delegation is DNS.\n+As the owner of a DNS domain, for example `.com`, I _delegate_ to another nameserver the responsibility for handing the subdomain `heptio.com`.\n+Any nameserver can hold a record for `heptio.com`, but without the linkage from the parent `.com` TLD, its information is unreachable and non authorative.\n+\n+Each _root_ of a DAG starts at a virtual host, which describes properties like the fully qualified name of the virtual host, any aliases (for example a www. prefix) of that vhost, TLS configuration, and possibly global access list details.\n+The vertices of a graph do not contain virtual host information, they are only reachable from a root via a delegation.\n+This permits the _owner_ of an ingress root to both delegate the authority to publish a service on a portion of the route space inside a virtual host, and to itself further delegate authority to publish and delegate.\n+\n+This also means that \n+\n+In practice the linkage, or delegation, from root to vertex, is performed with a specific type of route action.\n+You can think of it that rather than routing traffic to a service, it is routed to another ingressroute object for further processing.\n+\n+\n+##\n+\n+# Detailed Design\n+\n+## IngressRoute CRD\n+\n+This is an example of a fully populated root ingressroute.\n+\n+```yaml\n+apiVersion: contour.heptio.com/v1alpha1\n+kind: IngressRoute\n+metadata:\n+  name: google\n+  namespace: prod\n+spec:\n+  # virtualhost appears at most once. If it is present, the object is considered\n+  # to be a \"root\".\n+  virtualhost:\n+    # the fully qualified domain name of the root of the ingress tree\n+    # all leaves of the DAG rooted at this object relate to the fqdn (and its aliases)\n+    fqdn: www.google.com\n+    # a set of aliases for the domain, these may be alternative fqdns which are considered\n+    # aliases of the primary fqdn\n+    aliases:\n+      - www.google.com.au\n+      - google.com\n+    # if present describes tls properties. The CNI names that will be matched on\n+    # are described in fqdn and aliases, the tls.secretName secret must contain a\n+    # matching certificate\n+    tls:\n+      # required, the name of a secret in the current namespace\n+      secretName: google-tls\n+      # other properties like cipher suites may be added later\n+  # routes contains the set of routes for this virtual host.\n+  # routes must _always_ be present and non empty.\n+  # routes can be present in any order, and will be matched from most to least\n+  # specific.\n+  routes:\n+  # each route entry starts with a prefix match\n+  # and one of service or delegate\n+  - match: /static\n+    # service defines the properties of the service in the current namespace\n+    # that will handle traffic matching the route\n+    service:\n+    - name: google-static\n+      port: 9000\n+  - match: /finance\n+    # delegate delegates the matching route to another IngressRoute object.\n+    # This delegates the responsibility for /finance to the IngressRoute matching the delegate parameters\n+    delegate:\n+      # the name of the IngressRoute object to delegate to\n+      name: google-finance\n+      # the namespace of the IngressRoute object, if blank the current namespace is assumed\n+      namespace: finance\n+  - match: /ads\n+    # more than one service name/port pair may be present allowing the services for a route to\n+    # be handled by more than one service.\n+    service:\n+    - name: ads-red\n+      port: 9090\n+    - name: ads-blue\n+      port: 9090\n+```\n+\n+This is an example of the `google-finance` object which has been delegated responsibilty for paths starting with `/finance`.\n+\n+```yaml\n+apiVersion: contour.heptio.com/v1alpha1\n+kind: IngressRoute\n+metadata:\n+  name: google-finance\n+  namespace: finance\n+spec:\n+  # note that this is a vertex, so there is no virtualhost key\n+  # routes contains the set of routes for this virtual host.\n+  # routes must _always_ be present and non empty.\n+  # routes can be present in any order, and will be matched from most to least\n+  # specific, however as this is a vertex, only prefixes that match the prefix\n+  # that delegated to this object.\n+  routes:\n+  # each route in this object must start with /finance as this was the prefix which\n+  # delegated to this object.\n+  - match: /finance\n+    service:\n+    - name: finance-app\n+      port: 9999\n+  - match: /finance/static\n+    service:\n+    - name: finance-static-content\n+      port: 8080\n+  - match: /finance/partners\n+    # delegate the /finance/partners prefix to the partners namespace\n+    delegate:\n+      name: finance-partners\n+      namespace: partners\n+```\n+\n+## Delegation rules\n+\n+The delegation rules applied are as follows\n+\n+1. If an `IngressRoute` object contains a `spec.virtualhost` key it is considered a root.\n+2. If an `IngressRoute` object does not contain `spec.virtualhost` key is considered a vertex.","path":"design/ingressroute-design.md","position":147,"original_position":147,"commit_id":"e72be46cf546a110d0bf4b98a431291e6b80f259","original_commit_id":"e72be46cf546a110d0bf4b98a431291e6b80f259","user":{"login":"davecheney","id":7171,"avatar_url":"https://avatars0.githubusercontent.com/u/7171?v=4","gravatar_id":"","url":"https://api.github.com/users/davecheney","html_url":"https://github.com/davecheney","followers_url":"https://api.github.com/users/davecheney/followers","following_url":"https://api.github.com/users/davecheney/following{/other_user}","gists_url":"https://api.github.com/users/davecheney/gists{/gist_id}","starred_url":"https://api.github.com/users/davecheney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecheney/subscriptions","organizations_url":"https://api.github.com/users/davecheney/orgs","repos_url":"https://api.github.com/users/davecheney/repos","events_url":"https://api.github.com/users/davecheney/events{/privacy}","received_events_url":"https://api.github.com/users/davecheney/received_events","type":"User","site_admin":false},"body":"I've already changed this once and I just want to pick a terminology. My concern with using $THING and $non-THING is the easy of transposition from the less important to the more important. Ideally whatever words we use would not derive one from the negation of the other.","created_at":"2018-04-03T09:14:56Z","updated_at":"2018-04-03T09:14:56Z","html_url":"https://github.com/heptio/contour/pull/305#discussion_r178759906","pull_request_url":"https://api.github.com/repos/heptio/contour/pulls/305","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/heptio/contour/pulls/comments/178759906"},"html":{"href":"https://github.com/heptio/contour/pull/305#discussion_r178759906"},"pull_request":{"href":"https://api.github.com/repos/heptio/contour/pulls/305"}},"in_reply_to_id":178132586},"pull_request":{"url":"https://api.github.com/repos/heptio/contour/pulls/305","id":177971091,"html_url":"https://github.com/heptio/contour/pull/305","diff_url":"https://github.com/heptio/contour/pull/305.diff","patch_url":"https://github.com/heptio/contour/pull/305.patch","issue_url":"https://api.github.com/repos/heptio/contour/issues/305","number":305,"state":"open","locked":false,"title":"design: ingressroute first draft","user":{"login":"davecheney","id":7171,"avatar_url":"https://avatars0.githubusercontent.com/u/7171?v=4","gravatar_id":"","url":"https://api.github.com/users/davecheney","html_url":"https://github.com/davecheney","followers_url":"https://api.github.com/users/davecheney/followers","following_url":"https://api.github.com/users/davecheney/following{/other_user}","gists_url":"https://api.github.com/users/davecheney/gists{/gist_id}","starred_url":"https://api.github.com/users/davecheney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecheney/subscriptions","organizations_url":"https://api.github.com/users/davecheney/orgs","repos_url":"https://api.github.com/users/davecheney/repos","events_url":"https://api.github.com/users/davecheney/events{/privacy}","received_events_url":"https://api.github.com/users/davecheney/received_events","type":"User","site_admin":false},"body":"This document describes the design of a new CRD designed to replace the v1beta1.Ingress Kubernetes object. This new CRD will be integrated into Contour 0.5/0.6. Contour will continue to support the current v1beta1.Ingress object for as long as it is supported in upstream Kubernetes.\r\n\r\nSigned-off-by: Dave Cheney <dave@cheney.net>","created_at":"2018-03-28T08:58:45Z","updated_at":"2018-04-03T09:14:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a85dbfc6735ff36a9cea617d27569bd8d6678b48","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/heptio/contour/pulls/305/commits","review_comments_url":"https://api.github.com/repos/heptio/contour/pulls/305/comments","review_comment_url":"https://api.github.com/repos/heptio/contour/pulls/comments{/number}","comments_url":"https://api.github.com/repos/heptio/contour/issues/305/comments","statuses_url":"https://api.github.com/repos/heptio/contour/statuses/e72be46cf546a110d0bf4b98a431291e6b80f259","head":{"label":"davecheney:ingress-route","ref":"ingress-route","sha":"e72be46cf546a110d0bf4b98a431291e6b80f259","user":{"login":"davecheney","id":7171,"avatar_url":"https://avatars0.githubusercontent.com/u/7171?v=4","gravatar_id":"","url":"https://api.github.com/users/davecheney","html_url":"https://github.com/davecheney","followers_url":"https://api.github.com/users/davecheney/followers","following_url":"https://api.github.com/users/davecheney/following{/other_user}","gists_url":"https://api.github.com/users/davecheney/gists{/gist_id}","starred_url":"https://api.github.com/users/davecheney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecheney/subscriptions","organizations_url":"https://api.github.com/users/davecheney/orgs","repos_url":"https://api.github.com/users/davecheney/repos","events_url":"https://api.github.com/users/davecheney/events{/privacy}","received_events_url":"https://api.github.com/users/davecheney/received_events","type":"User","site_admin":false},"repo":{"id":108954185,"name":"contour","full_name":"davecheney/contour","owner":{"login":"davecheney","id":7171,"avatar_url":"https://avatars0.githubusercontent.com/u/7171?v=4","gravatar_id":"","url":"https://api.github.com/users/davecheney","html_url":"https://github.com/davecheney","followers_url":"https://api.github.com/users/davecheney/followers","following_url":"https://api.github.com/users/davecheney/following{/other_user}","gists_url":"https://api.github.com/users/davecheney/gists{/gist_id}","starred_url":"https://api.github.com/users/davecheney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecheney/subscriptions","organizations_url":"https://api.github.com/users/davecheney/orgs","repos_url":"https://api.github.com/users/davecheney/repos","events_url":"https://api.github.com/users/davecheney/events{/privacy}","received_events_url":"https://api.github.com/users/davecheney/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/davecheney/contour","description":"Contour is a Kubernetes ingress controller for Lyft's Envoy proxy.","fork":true,"url":"https://api.github.com/repos/davecheney/contour","forks_url":"https://api.github.com/repos/davecheney/contour/forks","keys_url":"https://api.github.com/repos/davecheney/contour/keys{/key_id}","collaborators_url":"https://api.github.com/repos/davecheney/contour/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/davecheney/contour/teams","hooks_url":"https://api.github.com/repos/davecheney/contour/hooks","issue_events_url":"https://api.github.com/repos/davecheney/contour/issues/events{/number}","events_url":"https://api.github.com/repos/davecheney/contour/events","assignees_url":"https://api.github.com/repos/davecheney/contour/assignees{/user}","branches_url":"https://api.github.com/repos/davecheney/contour/branches{/branch}","tags_url":"https://api.github.com/repos/davecheney/contour/tags","blobs_url":"https://api.github.com/repos/davecheney/contour/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/davecheney/contour/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/davecheney/contour/git/refs{/sha}","trees_url":"https://api.github.com/repos/davecheney/contour/git/trees{/sha}","statuses_url":"https://api.github.com/repos/davecheney/contour/statuses/{sha}","languages_url":"https://api.github.com/repos/davecheney/contour/languages","stargazers_url":"https://api.github.com/repos/davecheney/contour/stargazers","contributors_url":"https://api.github.com/repos/davecheney/contour/contributors","subscribers_url":"https://api.github.com/repos/davecheney/contour/subscribers","subscription_url":"https://api.github.com/repos/davecheney/contour/subscription","commits_url":"https://api.github.com/repos/davecheney/contour/commits{/sha}","git_commits_url":"https://api.github.com/repos/davecheney/contour/git/commits{/sha}","comments_url":"https://api.github.com/repos/davecheney/contour/comments{/number}","issue_comment_url":"https://api.github.com/repos/davecheney/contour/issues/comments{/number}","contents_url":"https://api.github.com/repos/davecheney/contour/contents/{+path}","compare_url":"https://api.github.com/repos/davecheney/contour/compare/{base}...{head}","merges_url":"https://api.github.com/repos/davecheney/contour/merges","archive_url":"https://api.github.com/repos/davecheney/contour/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/davecheney/contour/downloads","issues_url":"https://api.github.com/repos/davecheney/contour/issues{/number}","pulls_url":"https://api.github.com/repos/davecheney/contour/pulls{/number}","milestones_url":"https://api.github.com/repos/davecheney/contour/milestones{/number}","notifications_url":"https://api.github.com/repos/davecheney/contour/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/davecheney/contour/labels{/name}","releases_url":"https://api.github.com/repos/davecheney/contour/releases{/id}","deployments_url":"https://api.github.com/repos/davecheney/contour/deployments","created_at":"2017-10-31T06:22:59Z","updated_at":"2017-11-30T23:14:07Z","pushed_at":"2018-04-03T04:10:10Z","git_url":"git://github.com/davecheney/contour.git","ssh_url":"git@github.com:davecheney/contour.git","clone_url":"https://github.com/davecheney/contour.git","svn_url":"https://github.com/davecheney/contour","homepage":null,"size":1040,"stargazers_count":2,"watchers_count":2,"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":2,"default_branch":"master"}},"base":{"label":"heptio:master","ref":"master","sha":"1029f1bfab794598db4a104a807e8382d7a2786f","user":{"login":"heptio","id":22035492,"avatar_url":"https://avatars0.githubusercontent.com/u/22035492?v=4","gravatar_id":"","url":"https://api.github.com/users/heptio","html_url":"https://github.com/heptio","followers_url":"https://api.github.com/users/heptio/followers","following_url":"https://api.github.com/users/heptio/following{/other_user}","gists_url":"https://api.github.com/users/heptio/gists{/gist_id}","starred_url":"https://api.github.com/users/heptio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/heptio/subscriptions","organizations_url":"https://api.github.com/users/heptio/orgs","repos_url":"https://api.github.com/users/heptio/repos","events_url":"https://api.github.com/users/heptio/events{/privacy}","received_events_url":"https://api.github.com/users/heptio/received_events","type":"Organization","site_admin":false},"repo":{"id":108462822,"name":"contour","full_name":"heptio/contour","owner":{"login":"heptio","id":22035492,"avatar_url":"https://avatars0.githubusercontent.com/u/22035492?v=4","gravatar_id":"","url":"https://api.github.com/users/heptio","html_url":"https://github.com/heptio","followers_url":"https://api.github.com/users/heptio/followers","following_url":"https://api.github.com/users/heptio/following{/other_user}","gists_url":"https://api.github.com/users/heptio/gists{/gist_id}","starred_url":"https://api.github.com/users/heptio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/heptio/subscriptions","organizations_url":"https://api.github.com/users/heptio/orgs","repos_url":"https://api.github.com/users/heptio/repos","events_url":"https://api.github.com/users/heptio/events{/privacy}","received_events_url":"https://api.github.com/users/heptio/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/heptio/contour","description":"Contour is a Kubernetes ingress controller for Lyft's Envoy proxy.","fork":false,"url":"https://api.github.com/repos/heptio/contour","forks_url":"https://api.github.com/repos/heptio/contour/forks","keys_url":"https://api.github.com/repos/heptio/contour/keys{/key_id}","collaborators_url":"https://api.github.com/repos/heptio/contour/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/heptio/contour/teams","hooks_url":"https://api.github.com/repos/heptio/contour/hooks","issue_events_url":"https://api.github.com/repos/heptio/contour/issues/events{/number}","events_url":"https://api.github.com/repos/heptio/contour/events","assignees_url":"https://api.github.com/repos/heptio/contour/assignees{/user}","branches_url":"https://api.github.com/repos/heptio/contour/branches{/branch}","tags_url":"https://api.github.com/repos/heptio/contour/tags","blobs_url":"https://api.github.com/repos/heptio/contour/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/heptio/contour/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/heptio/contour/git/refs{/sha}","trees_url":"https://api.github.com/repos/heptio/contour/git/trees{/sha}","statuses_url":"https://api.github.com/repos/heptio/contour/statuses/{sha}","languages_url":"https://api.github.com/repos/heptio/contour/languages","stargazers_url":"https://api.github.com/repos/heptio/contour/stargazers","contributors_url":"https://api.github.com/repos/heptio/contour/contributors","subscribers_url":"https://api.github.com/repos/heptio/contour/subscribers","subscription_url":"https://api.github.com/repos/heptio/contour/subscription","commits_url":"https://api.github.com/repos/heptio/contour/commits{/sha}","git_commits_url":"https://api.github.com/repos/heptio/contour/git/commits{/sha}","comments_url":"https://api.github.com/repos/heptio/contour/comments{/number}","issue_comment_url":"https://api.github.com/repos/heptio/contour/issues/comments{/number}","contents_url":"https://api.github.com/repos/heptio/contour/contents/{+path}","compare_url":"https://api.github.com/repos/heptio/contour/compare/{base}...{head}","merges_url":"https://api.github.com/repos/heptio/contour/merges","archive_url":"https://api.github.com/repos/heptio/contour/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/heptio/contour/downloads","issues_url":"https://api.github.com/repos/heptio/contour/issues{/number}","pulls_url":"https://api.github.com/repos/heptio/contour/pulls{/number}","milestones_url":"https://api.github.com/repos/heptio/contour/milestones{/number}","notifications_url":"https://api.github.com/repos/heptio/contour/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/heptio/contour/labels{/name}","releases_url":"https://api.github.com/repos/heptio/contour/releases{/id}","deployments_url":"https://api.github.com/repos/heptio/contour/deployments","created_at":"2017-10-26T20:35:22Z","updated_at":"2018-04-03T08:07:54Z","pushed_at":"2018-04-03T04:10:06Z","git_url":"git://github.com/heptio/contour.git","ssh_url":"git@github.com:heptio/contour.git","clone_url":"https://github.com/heptio/contour.git","svn_url":"https://github.com/heptio/contour","homepage":null,"size":1111,"stargazers_count":729,"watchers_count":729,"language":"Go","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":64,"mirror_url":null,"archived":false,"open_issues_count":41,"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":64,"open_issues":41,"watchers":729,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/heptio/contour/pulls/305"},"html":{"href":"https://github.com/heptio/contour/pull/305"},"issue":{"href":"https://api.github.com/repos/heptio/contour/issues/305"},"comments":{"href":"https://api.github.com/repos/heptio/contour/issues/305/comments"},"review_comments":{"href":"https://api.github.com/repos/heptio/contour/pulls/305/comments"},"review_comment":{"href":"https://api.github.com/repos/heptio/contour/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/heptio/contour/pulls/305/commits"},"statuses":{"href":"https://api.github.com/repos/heptio/contour/statuses/e72be46cf546a110d0bf4b98a431291e6b80f259"}},"author_association":"OWNER"}}
{"actor":{"display_login":"davecheney"}}