Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
1af7ee74
Commit
1af7ee74
authored
Oct 13, 2017
by
Hasnain
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL-1282 | Created management command for automation of theme setup.
parent
8c205ad8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
331 additions
and
0 deletions
+331
-0
openedx/core/djangoapps/theming/management/commands/create_sites_and_configurations.py
+175
-0
openedx/core/djangoapps/theming/management/commands/tests/__init__.py
+0
-0
openedx/core/djangoapps/theming/management/commands/tests/test_create_sites_and_configurations.py
+156
-0
No files found.
openedx/core/djangoapps/theming/management/commands/create_sites_and_configurations.py
0 → 100644
View file @
1af7ee74
"""
This command will be run by an ansible script.
"""
import
os
import
json
import
fnmatch
import
logging
from
provider.oauth2.models
import
Client
from
provider.constants
import
CONFIDENTIAL
from
edx_oauth2_provider.models
import
TrustedClient
from
django.contrib.auth.models
import
User
from
django.contrib.sites.models
import
Site
from
django.core.management.base
import
BaseCommand
from
openedx.core.djangoapps.theming.models
import
SiteTheme
from
openedx.core.djangoapps.site_configuration.models
import
SiteConfiguration
LOG
=
logging
.
getLogger
(
__name__
)
class
Command
(
BaseCommand
):
"""
Command to create the site, site themes, configuration and oauth2 clients for all WL-sites.
Example:
./manage.py lms create_sites_and_configurations --dns-name whitelabel --theme-path /edx/src/edx-themes/edx-platform
"""
dns_name
=
None
theme_path
=
None
ecommerce_user
=
None
discovery_user
=
None
def
add_arguments
(
self
,
parser
):
"""
Add arguments to the command parser.
"""
parser
.
add_argument
(
"--dns-name"
,
type
=
str
,
help
=
"Enter DNS name of sandbox."
,
required
=
True
)
parser
.
add_argument
(
"--theme-path"
,
type
=
str
,
help
=
"Enter theme directory path"
,
required
=
True
)
def
_create_oauth2_client
(
self
,
url
,
site_name
,
is_discovery
=
True
):
"""
Creates the oauth2 client and add it in trusted clients.
"""
client
,
_
=
Client
.
objects
.
get_or_create
(
redirect_uri
=
"{url}complete/edx-oidc/"
.
format
(
url
=
url
),
defaults
=
{
"user"
:
self
.
discovery_user
if
is_discovery
else
self
.
ecommerce_user
,
"name"
:
"{site_name}_{client_type}_client"
.
format
(
site_name
=
site_name
,
client_type
=
"discovery"
if
is_discovery
else
"ecommerce"
,
),
"url"
:
url
,
"client_id"
:
"{client_type}-key-{site_name}"
.
format
(
client_type
=
"discovery"
if
is_discovery
else
"ecommerce"
,
site_name
=
site_name
),
"client_secret"
:
"{client_type}-secret-{dns_name}"
.
format
(
client_type
=
"discovery"
if
is_discovery
else
"ecommerce"
,
dns_name
=
self
.
dns_name
),
"client_type"
:
CONFIDENTIAL
,
"logout_uri"
:
"{url}logout/"
.
format
(
url
=
url
)
}
)
LOG
.
info
(
"Adding {client} oauth2 client as trusted client"
.
format
(
client
=
client
.
name
))
TrustedClient
.
objects
.
get_or_create
(
client
=
client
)
def
_create_sites
(
self
,
site_domain
,
theme_dir_name
,
site_configuration
):
"""
Create Sites, SiteThemes and SiteConfigurations
"""
site
,
created
=
Site
.
objects
.
get_or_create
(
domain
=
site_domain
,
defaults
=
{
"name"
:
theme_dir_name
}
)
if
created
:
LOG
.
info
(
"Creating '{site_name}' SiteTheme"
.
format
(
site_name
=
site_domain
))
SiteTheme
.
objects
.
create
(
site
=
site
,
theme_dir_name
=
theme_dir_name
)
LOG
.
info
(
"Creating '{site_name}' SiteConfiguration"
.
format
(
site_name
=
site_domain
))
SiteConfiguration
.
objects
.
create
(
site
=
site
,
values
=
site_configuration
,
enabled
=
True
)
else
:
LOG
.
info
(
"'{site_domain}' site already exists"
.
format
(
site_domain
=
site_domain
))
def
find
(
self
,
pattern
,
path
):
"""
Matched the given pattern in given path and returns the list of matching files
"""
result
=
[]
for
root
,
dirs
,
files
in
os
.
walk
(
path
):
# pylint: disable=unused-variable
for
name
in
files
:
if
fnmatch
.
fnmatch
(
name
,
pattern
):
result
.
append
(
os
.
path
.
join
(
root
,
name
))
return
result
def
_get_sites_data
(
self
):
"""
Reads the json files from theme directory and returns the site data in JSON format.
"site_a":{
"theme_dir_name": "site_a.edu.au"
"configuration": {
"key1": "value1",
"key2": "value2"
}
}
"""
site_data
=
{}
for
config_file
in
self
.
find
(
'sandbox_configuration.json'
,
self
.
theme_path
):
LOG
.
info
(
"Reading file from {file}"
.
format
(
file
=
config_file
))
configuration_data
=
json
.
loads
(
json
.
dumps
(
json
.
load
(
open
(
config_file
)
)
)
.
replace
(
"{dns_name}"
,
self
.
dns_name
)
)[
'lms_configuration'
]
site_data
[
configuration_data
[
'sandbox_name'
]]
=
{
"site_domain"
:
configuration_data
[
'site_domain'
],
"theme_dir_name"
:
configuration_data
[
'theme_dir_name'
],
"configuration"
:
configuration_data
[
'configuration'
]
}
return
site_data
def
get_or_create_service_user
(
self
,
username
):
"""
Creates the service user for ecommerce and discovery.
"""
return
User
.
objects
.
get_or_create
(
username
=
username
,
defaults
=
{
"is_staff"
:
True
,
"is_superuser"
:
True
}
)
def
handle
(
self
,
*
args
,
**
options
):
self
.
theme_path
=
options
[
'theme_path'
]
self
.
dns_name
=
options
[
'dns_name'
]
self
.
discovery_user
,
_
=
self
.
get_or_create_service_user
(
"lms_catalog_service_user"
)
self
.
ecommerce_user
,
_
=
self
.
get_or_create_service_user
(
"ecommerce_worker"
)
all_sites
=
self
.
_get_sites_data
()
# creating Sites, SiteThemes, SiteConfigurations and oauth2 clients
for
site_name
,
site_data
in
all_sites
.
items
():
site_domain
=
site_data
[
'site_domain'
]
discovery_url
=
"https://discovery-{site_domain}/"
.
format
(
site_domain
=
site_domain
)
ecommerce_url
=
"https://ecommerce-{site_domain}/"
.
format
(
site_domain
=
site_domain
)
LOG
.
info
(
"Creating '{site_name}' Site"
.
format
(
site_name
=
site_name
))
self
.
_create_sites
(
site_domain
,
site_data
[
'theme_dir_name'
],
site_data
[
'configuration'
])
LOG
.
info
(
"Creating discovery oauth2 client for '{site_name}' site"
.
format
(
site_name
=
site_name
))
self
.
_create_oauth2_client
(
discovery_url
,
site_name
,
is_discovery
=
True
)
LOG
.
info
(
"Creating ecommerce oauth2 client for '{site_name}' site"
.
format
(
site_name
=
site_name
))
self
.
_create_oauth2_client
(
ecommerce_url
,
site_name
,
is_discovery
=
False
)
openedx/core/djangoapps/theming/management/commands/tests/__init__.py
0 → 100644
View file @
1af7ee74
openedx/core/djangoapps/theming/management/commands/tests/test_create_sites_and_configurations.py
0 → 100644
View file @
1af7ee74
"""
Test cases for create_sites_and_configurations command.
"""
import
mock
from
django.test
import
TestCase
from
django.contrib.auth.models
import
User
from
django.contrib.sites.models
import
Site
from
django.core.management
import
call_command
,
CommandError
from
provider.oauth2.models
import
Client
from
edx_oauth2_provider.models
import
TrustedClient
from
openedx.core.djangoapps.theming.models
import
SiteTheme
SITES
=
[
'site_a'
,
'site_b'
]
def
_generate_site_config
(
dns_name
,
site_domain
):
""" Generate the site configuration for a given site """
return
{
"lms_url"
:
"{domain}-{dns_name}.sandbox.edx.org"
.
format
(
domain
=
site_domain
,
dns_name
=
dns_name
),
"platform_name"
:
"{domain}-{dns_name}"
.
format
(
domain
=
site_domain
,
dns_name
=
dns_name
)
}
def
_get_sites
(
dns_name
):
""" Creates the mocked data for management command """
sites
=
{}
for
site
in
SITES
:
sites
.
update
({
site
:
{
"theme_dir_name"
:
"{}_dir_name"
.
format
(
site
),
"configuration"
:
_generate_site_config
(
dns_name
,
site
),
"site_domain"
:
"{site}-{dns_name}.sandbox.edx.org"
.
format
(
site
=
site
,
dns_name
=
dns_name
)
}
})
return
sites
class
TestCreateSiteAndConfiguration
(
TestCase
):
""" Test the create_site_and_configuration command """
def
setUp
(
self
):
super
(
TestCreateSiteAndConfiguration
,
self
)
.
setUp
()
self
.
dns_name
=
"dummy_dns"
self
.
theme_path
=
"/dummyA/dummyB/"
def
_assert_sites_are_valid
(
self
):
"""
Checks that data of all sites is valid
"""
sites
=
Site
.
objects
.
all
()
# there is an extra default site.
self
.
assertEqual
(
len
(
sites
),
len
(
SITES
)
+
1
)
for
site
in
sites
:
if
site
.
name
in
SITES
:
site_theme
=
SiteTheme
.
objects
.
get
(
site
=
site
)
self
.
assertEqual
(
site_theme
.
theme_dir_name
,
"{}_dir_name"
.
format
(
site
.
name
)
)
self
.
assertDictEqual
(
dict
(
site
.
configuration
.
values
),
_generate_site_config
(
self
.
dns_name
,
site
.
name
)
)
def
_assert_ecommerce_clients_are_valid
(
self
):
"""
Checks that all ecommerce clients are valid
"""
service_user
=
User
.
objects
.
filter
(
username
=
"ecommerce_worker"
)
self
.
assertEqual
(
len
(
service_user
),
1
)
self
.
assertTrue
(
service_user
[
0
]
.
is_staff
)
clients
=
Client
.
objects
.
filter
(
user
=
service_user
)
self
.
assertEqual
(
len
(
clients
),
len
(
SITES
))
for
client
in
clients
:
self
.
assertEqual
(
client
.
user
.
username
,
service_user
[
0
]
.
username
)
site_name
=
client
.
name
[:
6
]
ecommerce_url
=
"https://ecommerce-{site_name}-{dns_name}.sandbox.edx.org/"
.
format
(
site_name
=
site_name
,
dns_name
=
self
.
dns_name
)
self
.
assertEqual
(
client
.
url
,
ecommerce_url
)
self
.
assertEqual
(
client
.
redirect_uri
,
"{ecommerce_url}complete/edx-oidc/"
.
format
(
ecommerce_url
=
ecommerce_url
)
)
self
.
assertEqual
(
len
(
TrustedClient
.
objects
.
filter
(
client
=
client
)),
1
)
def
_assert_discovery_clients_are_valid
(
self
):
"""
Checks that all discovery clients are valid
"""
service_user
=
User
.
objects
.
filter
(
username
=
"lms_catalog_service_user"
)
self
.
assertEqual
(
len
(
service_user
),
1
)
self
.
assertTrue
(
service_user
[
0
]
.
is_staff
)
clients
=
Client
.
objects
.
filter
(
user
=
service_user
)
self
.
assertEqual
(
len
(
clients
),
len
(
SITES
))
for
client
in
clients
:
self
.
assertEqual
(
client
.
user
.
username
,
service_user
[
0
]
.
username
)
site_name
=
client
.
name
[:
6
]
discovery_url
=
"https://discovery-{site_name}-{dns_name}.sandbox.edx.org/"
.
format
(
site_name
=
site_name
,
dns_name
=
self
.
dns_name
)
self
.
assertEqual
(
client
.
url
,
discovery_url
)
self
.
assertEqual
(
client
.
redirect_uri
,
"{discovery_url}complete/edx-oidc/"
.
format
(
discovery_url
=
discovery_url
)
)
self
.
assertEqual
(
len
(
TrustedClient
.
objects
.
filter
(
client
=
client
)),
1
)
def
test_without_dns
(
self
):
""" Test the command without dns_name """
with
self
.
assertRaises
(
CommandError
):
call_command
(
"create_sites_and_configurations"
)
@mock.patch
(
'openedx.core.djangoapps.theming.management.commands.create_sites_and_configurations.Command._get_sites_data'
)
def
test_with_dns
(
self
,
mock_get_sites
):
""" Test the command with dns_name """
mock_get_sites
.
return_value
=
_get_sites
(
self
.
dns_name
)
call_command
(
"create_sites_and_configurations"
,
"--dns-name"
,
self
.
dns_name
,
"--theme-path"
,
self
.
theme_path
)
self
.
_assert_sites_are_valid
()
self
.
_assert_discovery_clients_are_valid
()
self
.
_assert_ecommerce_clients_are_valid
()
call_command
(
"create_sites_and_configurations"
,
"--dns-name"
,
self
.
dns_name
,
"--theme-path"
,
self
.
theme_path
)
# if we run command with same dns then it will not duplicates the sites and oauth2 clients.
self
.
_assert_sites_are_valid
()
self
.
_assert_discovery_clients_are_valid
()
self
.
_assert_ecommerce_clients_are_valid
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment