{"action":"created","comment":{"url":"https://api.github.com/repos/open-craft/opencraft/pulls/comments/66030683","id":66030683,"diff_hunk":"@@ -52,73 +62,105 @@ class OpenEdXInstance(Instance, OpenEdXAppConfiguration, OpenEdXDatabaseMixin, O\n     \"\"\"\n \n     # Most settings/fields are inherited from OpenEdXAppConfiguration\n-    sub_domain = models.CharField(max_length=50)\n-    base_domain = models.CharField(max_length=50, blank=True)\n+\n+    # Internal domains are controlled by us and their DNS records are automatically set to point to the current active\n+    # appserver. They are generated from a unique prefix (given as 'sub_domain' in instance factories) and the value of\n+    # DEFAULT_INSTANCE_BASE_DOMAIN at instance creation time. They cannot be blank and are normally never changed after\n+    # the instance is created.\n+    # External domains on the other hand are controlled by the customer and are optional. We use external domains in\n+    # preference to internal domains when displaying links to the instance in the UI and when passing domain related\n+    # settings to ansible vars when provisioning appservers.\n+    # The `domain`, `lms_preview_domain`, and `studio_domain` methods are useful when you need to access the external\n+    # domain if present, otherwise fall back to the corresponding internal domain.","path":"instance/models/openedx_instance.py","position":32,"original_position":32,"commit_id":"7ca4acf420d8d29cfc8ffb0fe68e50e85cfa0be2","original_commit_id":"7ca4acf420d8d29cfc8ffb0fe68e50e85cfa0be2","user":{"login":"mtyaka","id":32585,"avatar_url":"https://avatars.githubusercontent.com/u/32585?v=3","gravatar_id":"","url":"https://api.github.com/users/mtyaka","html_url":"https://github.com/mtyaka","followers_url":"https://api.github.com/users/mtyaka/followers","following_url":"https://api.github.com/users/mtyaka/following{/other_user}","gists_url":"https://api.github.com/users/mtyaka/gists{/gist_id}","starred_url":"https://api.github.com/users/mtyaka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mtyaka/subscriptions","organizations_url":"https://api.github.com/users/mtyaka/orgs","repos_url":"https://api.github.com/users/mtyaka/repos","events_url":"https://api.github.com/users/mtyaka/events{/privacy}","received_events_url":"https://api.github.com/users/mtyaka/received_events","type":"User","site_admin":false},"body":"@itsjeyd Much better, thank you :)","created_at":"2016-06-07T08:40:56Z","updated_at":"2016-06-07T08:40:56Z","html_url":"https://github.com/open-craft/opencraft/pull/98#discussion_r66030683","pull_request_url":"https://api.github.com/repos/open-craft/opencraft/pulls/98","_links":{"self":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/comments/66030683"},"html":{"href":"https://github.com/open-craft/opencraft/pull/98#discussion_r66030683"},"pull_request":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/98"}}},"pull_request":{"url":"https://api.github.com/repos/open-craft/opencraft/pulls/98","id":72301565,"html_url":"https://github.com/open-craft/opencraft/pull/98","diff_url":"https://github.com/open-craft/opencraft/pull/98.diff","patch_url":"https://github.com/open-craft/opencraft/pull/98.patch","issue_url":"https://api.github.com/repos/open-craft/opencraft/issues/98","number":98,"state":"open","locked":false,"title":"Add support for custom instance domains","user":{"login":"mtyaka","id":32585,"avatar_url":"https://avatars.githubusercontent.com/u/32585?v=3","gravatar_id":"","url":"https://api.github.com/users/mtyaka","html_url":"https://github.com/mtyaka","followers_url":"https://api.github.com/users/mtyaka/followers","following_url":"https://api.github.com/users/mtyaka/following{/other_user}","gists_url":"https://api.github.com/users/mtyaka/gists{/gist_id}","starred_url":"https://api.github.com/users/mtyaka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mtyaka/subscriptions","organizations_url":"https://api.github.com/users/mtyaka/orgs","repos_url":"https://api.github.com/users/mtyaka/repos","events_url":"https://api.github.com/users/mtyaka/events{/privacy}","received_events_url":"https://api.github.com/users/mtyaka/received_events","type":"User","site_admin":false},"body":"**Background**\r\n\r\nWe want customers to be able to access their instances from their own custom domains which we don't control. We have to use custom domains in edx-platform ansible configuration when provisioning new app servers, but we still need to set DNS entries for the internal (*.opencraft.hosting) domains. The customer will create a CNAME entry pointing their custom domains to the internal *.opencraft.hosting domain.\r\n\r\nThe patch adds three new fields to instance configuration:\r\n\r\n- external_lms_domain\r\n- external_lms_preview_domain\r\n- external_studio_domain\r\n\r\nWhen set, the external domains are used instead of the internal (opencraft-controlled) domains in ansible configuration and the UI.\r\n\r\nRegardless of the presence of external domains, each instance is still assigned an internal domain and the DNS entry for the internal domain is always updated to point to the current active appserver.\r\n\r\nCustomers who use external domains will have to set a CNAME record that points to the main internal domain.\r\n\r\n**Testing**\r\n\r\n1. Create a new OpenEdXInstance (or use an existing one) and set `external_lms_domain`, `external_lms_preview_domain`, and `external_studio_domain` to custom values (for example `courses.mydomain.org`, `preview.mydomain.org`, `studio.mydomain.org`). You can do that either using the django console or the django admin UI.\r\n2. Make sure that LMS and Studio URLs displayed in the UI point to the external domain.\r\n3. Provision a new appserver and make sure that `COMMON_HOSTNAME`, `EDXAPP_LMS_BASE`, `EDXAPP_PREVIEW_LMS_BASE`, and `EDXAPP_CMS_BASE` are using external rather than internal domains.\r\n4. Activate the new app server and make sure that it uses the internal domain rather than external domain when setting DNS entries.\r\n5. Check that everything still works correctly for instances without external domains (internal domains should be used everywhere).","created_at":"2016-06-02T07:40:31Z","updated_at":"2016-06-07T08:40:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"18da59ebb0865fbcff2b246b0ad89ac63c53c301","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/open-craft/opencraft/pulls/98/commits","review_comments_url":"https://api.github.com/repos/open-craft/opencraft/pulls/98/comments","review_comment_url":"https://api.github.com/repos/open-craft/opencraft/pulls/comments{/number}","comments_url":"https://api.github.com/repos/open-craft/opencraft/issues/98/comments","statuses_url":"https://api.github.com/repos/open-craft/opencraft/statuses/7ca4acf420d8d29cfc8ffb0fe68e50e85cfa0be2","head":{"label":"open-craft:mtyaka/external-domains","ref":"mtyaka/external-domains","sha":"7ca4acf420d8d29cfc8ffb0fe68e50e85cfa0be2","user":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"repo":{"id":40447973,"name":"opencraft","full_name":"open-craft/opencraft","owner":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/open-craft/opencraft","description":"OpenCraft - Instance Manager","fork":false,"url":"https://api.github.com/repos/open-craft/opencraft","forks_url":"https://api.github.com/repos/open-craft/opencraft/forks","keys_url":"https://api.github.com/repos/open-craft/opencraft/keys{/key_id}","collaborators_url":"https://api.github.com/repos/open-craft/opencraft/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/open-craft/opencraft/teams","hooks_url":"https://api.github.com/repos/open-craft/opencraft/hooks","issue_events_url":"https://api.github.com/repos/open-craft/opencraft/issues/events{/number}","events_url":"https://api.github.com/repos/open-craft/opencraft/events","assignees_url":"https://api.github.com/repos/open-craft/opencraft/assignees{/user}","branches_url":"https://api.github.com/repos/open-craft/opencraft/branches{/branch}","tags_url":"https://api.github.com/repos/open-craft/opencraft/tags","blobs_url":"https://api.github.com/repos/open-craft/opencraft/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/open-craft/opencraft/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/open-craft/opencraft/git/refs{/sha}","trees_url":"https://api.github.com/repos/open-craft/opencraft/git/trees{/sha}","statuses_url":"https://api.github.com/repos/open-craft/opencraft/statuses/{sha}","languages_url":"https://api.github.com/repos/open-craft/opencraft/languages","stargazers_url":"https://api.github.com/repos/open-craft/opencraft/stargazers","contributors_url":"https://api.github.com/repos/open-craft/opencraft/contributors","subscribers_url":"https://api.github.com/repos/open-craft/opencraft/subscribers","subscription_url":"https://api.github.com/repos/open-craft/opencraft/subscription","commits_url":"https://api.github.com/repos/open-craft/opencraft/commits{/sha}","git_commits_url":"https://api.github.com/repos/open-craft/opencraft/git/commits{/sha}","comments_url":"https://api.github.com/repos/open-craft/opencraft/comments{/number}","issue_comment_url":"https://api.github.com/repos/open-craft/opencraft/issues/comments{/number}","contents_url":"https://api.github.com/repos/open-craft/opencraft/contents/{+path}","compare_url":"https://api.github.com/repos/open-craft/opencraft/compare/{base}...{head}","merges_url":"https://api.github.com/repos/open-craft/opencraft/merges","archive_url":"https://api.github.com/repos/open-craft/opencraft/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/open-craft/opencraft/downloads","issues_url":"https://api.github.com/repos/open-craft/opencraft/issues{/number}","pulls_url":"https://api.github.com/repos/open-craft/opencraft/pulls{/number}","milestones_url":"https://api.github.com/repos/open-craft/opencraft/milestones{/number}","notifications_url":"https://api.github.com/repos/open-craft/opencraft/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/open-craft/opencraft/labels{/name}","releases_url":"https://api.github.com/repos/open-craft/opencraft/releases{/id}","deployments_url":"https://api.github.com/repos/open-craft/opencraft/deployments","created_at":"2015-08-09T19:35:05Z","updated_at":"2016-05-25T11:23:15Z","pushed_at":"2016-06-07T08:21:57Z","git_url":"git://github.com/open-craft/opencraft.git","ssh_url":"git@github.com:open-craft/opencraft.git","clone_url":"https://github.com/open-craft/opencraft.git","svn_url":"https://github.com/open-craft/opencraft","homepage":null,"size":2205,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":10,"forks":8,"open_issues":10,"watchers":7,"default_branch":"master"}},"base":{"label":"open-craft:master","ref":"master","sha":"c24d0be5e53891a9e65d52b9172a96f6f67bc073","user":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"repo":{"id":40447973,"name":"opencraft","full_name":"open-craft/opencraft","owner":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/open-craft/opencraft","description":"OpenCraft - Instance Manager","fork":false,"url":"https://api.github.com/repos/open-craft/opencraft","forks_url":"https://api.github.com/repos/open-craft/opencraft/forks","keys_url":"https://api.github.com/repos/open-craft/opencraft/keys{/key_id}","collaborators_url":"https://api.github.com/repos/open-craft/opencraft/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/open-craft/opencraft/teams","hooks_url":"https://api.github.com/repos/open-craft/opencraft/hooks","issue_events_url":"https://api.github.com/repos/open-craft/opencraft/issues/events{/number}","events_url":"https://api.github.com/repos/open-craft/opencraft/events","assignees_url":"https://api.github.com/repos/open-craft/opencraft/assignees{/user}","branches_url":"https://api.github.com/repos/open-craft/opencraft/branches{/branch}","tags_url":"https://api.github.com/repos/open-craft/opencraft/tags","blobs_url":"https://api.github.com/repos/open-craft/opencraft/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/open-craft/opencraft/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/open-craft/opencraft/git/refs{/sha}","trees_url":"https://api.github.com/repos/open-craft/opencraft/git/trees{/sha}","statuses_url":"https://api.github.com/repos/open-craft/opencraft/statuses/{sha}","languages_url":"https://api.github.com/repos/open-craft/opencraft/languages","stargazers_url":"https://api.github.com/repos/open-craft/opencraft/stargazers","contributors_url":"https://api.github.com/repos/open-craft/opencraft/contributors","subscribers_url":"https://api.github.com/repos/open-craft/opencraft/subscribers","subscription_url":"https://api.github.com/repos/open-craft/opencraft/subscription","commits_url":"https://api.github.com/repos/open-craft/opencraft/commits{/sha}","git_commits_url":"https://api.github.com/repos/open-craft/opencraft/git/commits{/sha}","comments_url":"https://api.github.com/repos/open-craft/opencraft/comments{/number}","issue_comment_url":"https://api.github.com/repos/open-craft/opencraft/issues/comments{/number}","contents_url":"https://api.github.com/repos/open-craft/opencraft/contents/{+path}","compare_url":"https://api.github.com/repos/open-craft/opencraft/compare/{base}...{head}","merges_url":"https://api.github.com/repos/open-craft/opencraft/merges","archive_url":"https://api.github.com/repos/open-craft/opencraft/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/open-craft/opencraft/downloads","issues_url":"https://api.github.com/repos/open-craft/opencraft/issues{/number}","pulls_url":"https://api.github.com/repos/open-craft/opencraft/pulls{/number}","milestones_url":"https://api.github.com/repos/open-craft/opencraft/milestones{/number}","notifications_url":"https://api.github.com/repos/open-craft/opencraft/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/open-craft/opencraft/labels{/name}","releases_url":"https://api.github.com/repos/open-craft/opencraft/releases{/id}","deployments_url":"https://api.github.com/repos/open-craft/opencraft/deployments","created_at":"2015-08-09T19:35:05Z","updated_at":"2016-05-25T11:23:15Z","pushed_at":"2016-06-07T08:21:57Z","git_url":"git://github.com/open-craft/opencraft.git","ssh_url":"git@github.com:open-craft/opencraft.git","clone_url":"https://github.com/open-craft/opencraft.git","svn_url":"https://github.com/open-craft/opencraft","homepage":null,"size":2205,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":10,"forks":8,"open_issues":10,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/98"},"html":{"href":"https://github.com/open-craft/opencraft/pull/98"},"issue":{"href":"https://api.github.com/repos/open-craft/opencraft/issues/98"},"comments":{"href":"https://api.github.com/repos/open-craft/opencraft/issues/98/comments"},"review_comments":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/98/comments"},"review_comment":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/98/commits"},"statuses":{"href":"https://api.github.com/repos/open-craft/opencraft/statuses/7ca4acf420d8d29cfc8ffb0fe68e50e85cfa0be2"}}}}
{"actor":{"display_login":"mtyaka"}}