{"action":"created","issue":{"url":"https://api.github.com/repos/hashicorp/consul/issues/1159","repository_url":"https://api.github.com/repos/hashicorp/consul","labels_url":"https://api.github.com/repos/hashicorp/consul/issues/1159/labels{/name}","comments_url":"https://api.github.com/repos/hashicorp/consul/issues/1159/comments","events_url":"https://api.github.com/repos/hashicorp/consul/issues/1159/events","html_url":"https://github.com/hashicorp/consul/issues/1159","id":99461275,"number":1159,"title":"Support server-side hierarchial lookups using optional `parent` DC configuration property","user":{"login":"bacoboy","id":874597,"avatar_url":"https://avatars.githubusercontent.com/u/874597?v=3","gravatar_id":"","url":"https://api.github.com/users/bacoboy","html_url":"https://github.com/bacoboy","followers_url":"https://api.github.com/users/bacoboy/followers","following_url":"https://api.github.com/users/bacoboy/following{/other_user}","gists_url":"https://api.github.com/users/bacoboy/gists{/gist_id}","starred_url":"https://api.github.com/users/bacoboy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bacoboy/subscriptions","organizations_url":"https://api.github.com/users/bacoboy/orgs","repos_url":"https://api.github.com/users/bacoboy/repos","events_url":"https://api.github.com/users/bacoboy/events{/privacy}","received_events_url":"https://api.github.com/users/bacoboy/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/hashicorp/consul/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2015-08-06T15:21:37Z","updated_at":"2016-04-13T07:26:49Z","closed_at":"2016-04-13T07:26:49Z","body":"Support server-side hierarchial lookups using optional `parent` DC configuration property\r\n\r\nWhile I know that issue #154 is related to address some kind of fallback processing when a service isn't found in the queried datacenter, I'm looking for something different which I don't think has been discussed yet.\r\n\r\nIn the current implementation, the logic looks something like this:\r\n\r\n    if service request DC.nil? // DC specified in query?\r\n      service = service.myDC // If not append my DC\r\n    end\r\n    if service.DC found: // Look it up specifically\r\n      return service.DC  // Got one\r\n    else\r\n      return NOT FOUND   // Sorry Charlie!\r\n    end\r\n    \r\nThe proposed implementation in #154 pushes HOW the lookup should fallback into the query issued (meaning, the client would need to know) to something like this:\r\n\r\n    if service request DC.nil? // DC not specified in query\r\n      if service.myDC exists: // See if I have one locally (this part is the same as above)\r\n        return service.myDC\r\n      else\r\n        return NOT FOUND\r\n      end\r\n    else\r\n      if service.DC=XXXX matches something: // Client passes specific DC or pattern to match\r\n        return service.XXXXX // Found it\r\n      else\r\n        return NOT FOUND // Sorry charlie!\r\n      end\r\n    end\r\n\r\nWhat I am proposing is managing the fallback logic in the consul configurations server-side by creating a parent relationship between the consul clsuters (known via less chatty WAN) that the client doesn't need to know anything about.  It would use the WAN relationship and an optional configuration on the server side called `parent`.  This is the fallback DC to use if there is no match when one is specified.  And you keep asking up the chain until something in found (or not).  In pseudocode:\r\n\r\n    if service request DC.nil? // DC not specified\r\n      if service.THIS_DC exists // check locally\r\n        return service.THIS_DC  // found locally\r\n      else\r\n        if parent property set?\r\n          return lookup(service.PARENT, WAN)  // ask parent\r\n        else\r\n          return NOT FOUND // current logic for compatability\r\n        end\r\n      end\r\n    else\r\n      if service.DC=XXXX matches something:  // asked for something specific\r\n        return service.XXXXX  // return if I know about it\r\n      else\r\n        return NOT FOUND // you asked for specific and it doesn't exist\r\n      end\r\n    end\r\n\r\nThe `lookup(service.PARENT, WAN)` means, do a pass-thru call to the configured `parent` DC.  This seems like it would scale much better and deal with geographic configurations such as this:\r\n\r\n\r\n```\r\n                       +------------+                                                                   \r\n +---------------+     |            |  parent=ap-southeast-1                                            \r\n |Client in China+---> | cn-north-1 |                                                                   \r\n +---------------+     |            |                                                                   \r\n                       +-------+----+                                +-----------+                      \r\n                               |                    parent=us-east+1 |           |       +-------------+\r\n                               v                                     | eu-west-1 | <-----+Client in LON|\r\n                                                                     |           |       +-------------+\r\n                       +----------------+                            +----+------+                      \r\n+--------------+       |                | parent=us-west-1                |                             \r\n|Client in Asia+-----> | ap-southeast-1 |                                 |                             \r\n+--------------+       |                |                                 |                             \r\n                       +--------+-------+                                 |                             \r\n                                |                                         |                             \r\n                                |                                         |                             \r\n                                v                                         v                             \r\n                                                                                                        \r\n                         +-----------+                              +-----------+                       \r\n+-------------+          |           | parent=us-east-1             |           |     +-------------+   \r\n|Client in SFO+------->  | us-west-1 |                              | us-east-1 | <---+Client in NYC|   \r\n+-------------+          |           | +--------------------------> |           |     +-------------+   \r\n                         +-----------+                              +-----------+                       \r\n```\r\n\r\nIn this example, I'm trying to serve customers in london, china, and the US.  \r\nI certainly don't want people in london calling \"local\" services in asia, I'd run those in eu-west-1.  Chances are there are services I can only run centrally (say a service that backs the central inventory DB -- in this example us-east-1).  Let's say that I don't have a license to sell things in china so I move those services to asia, but I serve static content out of china to not hit my customers with china firewall processing.\r\n\r\nIn this way, I use GSLB load balancing to find \"close\" entry points to the site, but once in the system, if I can't find what I need \"close\" I keep going UP until I find what I need.  If I can't find it ANYWHERE, THEN return a NOT FOUND.\r\n\r\nClearly it is assumed people don't create loops in their configurations...\r\n\r\nI believe this could be done quicker than #154 since the API wouldn't change and the semantics are the same if `parent` isn't configured.  It also keeps decision logic off the client since they shouldn't care what the fallback plan should be -- they just want an answer...\r\n\r\nLooking back on my notes this is also related to #208 so referencing here for completeness...\r\n\r\nThoughts?"},"comment":{"url":"https://api.github.com/repos/hashicorp/consul/issues/comments/209270810","html_url":"https://github.com/hashicorp/consul/issues/1159#issuecomment-209270810","issue_url":"https://api.github.com/repos/hashicorp/consul/issues/1159","id":209270810,"user":{"login":"slackpad","id":673509,"avatar_url":"https://avatars.githubusercontent.com/u/673509?v=3","gravatar_id":"","url":"https://api.github.com/users/slackpad","html_url":"https://github.com/slackpad","followers_url":"https://api.github.com/users/slackpad/followers","following_url":"https://api.github.com/users/slackpad/following{/other_user}","gists_url":"https://api.github.com/users/slackpad/gists{/gist_id}","starred_url":"https://api.github.com/users/slackpad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/slackpad/subscriptions","organizations_url":"https://api.github.com/users/slackpad/orgs","repos_url":"https://api.github.com/users/slackpad/repos","events_url":"https://api.github.com/users/slackpad/events{/privacy}","received_events_url":"https://api.github.com/users/slackpad/received_events","type":"User","site_admin":false},"created_at":"2016-04-13T07:26:49Z","updated_at":"2016-04-13T07:26:49Z","body":"Closing this out - [prepared query templates](https://www.consul.io/docs/agent/http/query.html#templates) allow you prefix match service names (up to an empty prefix that matches any service). This shipped in 0.6.4 so I think we are good here. Please let me know if you have any questions."}}