Skip to content

Commit

Permalink
feat: enable dynamic config
Browse files Browse the repository at this point in the history
 This change does a couple of things and it introduce breaking
 changes, in summary it does:
  - It remove the usage of env/(productoin/development)
  - It's no longer possible to set/override MFE config via
    MFE_APP_*
  - It make MFEs rely to config that are defied in LMS
    settins
  - Other essetinal config that are needed at build time are
    are defined in the Dockerfile
  - It sets a proxy for both Caddy (for production) and Webpack
    (for development)
  - For old patches that are used to set/override MFE config, via
    production/development would need to be rewritten
  • Loading branch information
ghassanmas authored and arbrandes committed Dec 7, 2022
1 parent f4129d1 commit 9ad9263
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 101 deletions.
1 change: 1 addition & 0 deletions tutormfe/patches/caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
request_body {
max_size 2MB
}
reverse_proxy /api/mfe_config/v1* lms:8000
import proxy "mfe:8002"
}
25 changes: 25 additions & 0 deletions tutormfe/patches/openedx-lms-development-settings
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,28 @@ CORS_ORIGIN_WHITELIST.append("http://{{ MFE_HOST }}:{{ app["port"] }}")
LOGIN_REDIRECT_WHITELIST.append("{{ MFE_HOST }}:{{ app["port"] }}")
CSRF_TRUSTED_ORIGINS.append("{{ MFE_HOST }}:{{ app["port"] }}")
{% endfor %}

# Start of Dynamic config API settings

ENABLE_MFE_CONFIG_API = True

MFE_CONFIG = {
"BASE_URL": "{{ MFE_HOST }}",
"CREDENTIALS_BASE_URL": "/csrf/api/v1/token",
"DISCOVERY_API_BASE_URL": "{% if DISCOVERY_HOST is defined %}http://{{ DISCOVERY_HOST }}:8381{% endif %}",
"FAVICON_URL": "http://{{ LMS_HOST }}/favicon.ico",
"LANGUAGE_PREFERENCE_COOKIE_NAME": "openedx-language-preference",
"LMS_BASE_URL": "http://{{ LMS_HOST }}:8000",
"LOGIN_URL": "http://{{ LMS_HOST }}:8000/login",
"LOGO_URL": "http://{{ LMS_HOST }}:8000/theming/asset/images/logo.png",
"LOGO_TRADEMARK_URL": "http://{{ LMS_HOST }}:8000/theming/asset/images/logo.png",
"LOGOUT_URL": "http://{{ LMS_HOST }}:8000/logout",
"MARKETING_SITE_BASE_URL": "http://{{ LMS_HOST }}:8000",
"REFRESH_ACCESS_TOKEN_ENDPOINT": "http://{{ LMS_HOST }}:8000/login_refresh",
"SITE_NAME": "{{ PLATFORM_NAME }}",
"STUDIO_BASE_URL": "http://{{ CMS_HOST }}:8001",
"USER_INFO_COOKIE_NAME": "user-info",
"ACCESS_TOKEN_COOKIE_NAME": "edx-jwt-cookie-header-payload",
}

# Ends Dynamic config API settings
28 changes: 28 additions & 0 deletions tutormfe/patches/openedx-lms-production-settings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,31 @@ PROFILE_MICROFRONTEND_URL = "{% if ENABLE_HTTPS %}https://{% else %}http://{% en
LOGIN_REDIRECT_WHITELIST.append("{{ MFE_HOST }}")
CORS_ORIGIN_WHITELIST.append("{% if ENABLE_HTTPS %}https://{% else %}http://{% endif %}{{ MFE_HOST }}")
CSRF_TRUSTED_ORIGINS.append("{{ MFE_HOST }}")

ALLOWED_HOSTS.append("{{ MFE_HOST }}")

# Start of Dynamic config API settings

ENABLE_MFE_CONFIG_API = True

MFE_CONFIG = {
"BASE_URL": "{{ MFE_HOST }}",
"CREDENTIALS_BASE_URL": "/csrf/api/v1/token",
"DISCOVERY_API_BASE_URL": "{% if DISCOVERY_HOST is defined %}{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ DISCOVERY_HOST }}{% endif %}",
"FAVICON_URL": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}/favicon.ico",
"LANGUAGE_PREFERENCE_COOKIE_NAME": "openedx-language-preference",
"LMS_BASE_URL": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}",
"LOGIN_URL": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}/login",
"LOGO_URL": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}/theming/asset/images/logo.png",
"LOGO_TRADEMARK_URL": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}/theming/asset/images/logo.png",
"LOGOUT_URL": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}/logout",
"MARKETING_SITE_BASE_URL": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}",
"REFRESH_ACCESS_TOKEN_ENDPOINT": "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}/login_refresh",
"SITE_NAME": "{{ PLATFORM_NAME }}",
"STUDIO_BASE_URL": "{{ "https" if ENABLE_HTTPS else "http" }}://{{ CMS_HOST }}",
"USER_INFO_COOKIE_NAME": "user-info",
"ACCESS_TOKEN_COOKIE_NAME": "edx-jwt-cookie-header-payload",
}


# Ends Dynamic config API settings
59 changes: 22 additions & 37 deletions tutormfe/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pkg_resources

from tutor import hooks as tutor_hooks
from tutor.hooks import priorities

from .__about__ import __version__

Expand All @@ -15,34 +16,23 @@
"CADDY_DOCKER_IMAGE": "{{ DOCKER_IMAGE_CADDY }}",
"ACCOUNT_MFE_APP": {
"name": "account",
"repository": "https://github.com/edx/frontend-app-account",
"repository": "https://github.com/openedx/frontend-app-account",
"port": 1997,
"env": {
"production": {
"COACHING_ENABLED": "",
"ENABLE_DEMOGRAPHICS_COLLECTION": "",
},
},
},
"GRADEBOOK_MFE_APP": {
"name": "gradebook",
"repository": "https://github.com/edx/frontend-app-gradebook",
"repository": "https://github.com/openedx/frontend-app-gradebook",
"port": 1994,
},
"LEARNING_MFE_APP": {
"name": "learning",
"repository": "https://github.com/edx/frontend-app-learning",
"repository": "https://github.com/openedx/frontend-app-learning",
"port": 2000,
},
"PROFILE_MFE_APP": {
"name": "profile",
"repository": "https://github.com/edx/frontend-app-profile",
"repository": "https://github.com/openedx/frontend-app-profile",
"port": 1995,
"env": {
"production": {
"ENABLE_LEARNER_RECORD_MFE": "true",
},
},
},
},
}
Expand All @@ -62,6 +52,15 @@
)
)

tutor_hooks.Filters.IMAGES_PULL.add_item((
"mfe",
"{{ MFE_DOCKER_IMAGE }}",
))
tutor_hooks.Filters.IMAGES_PUSH.add_item((
"mfe",
"{{ MFE_DOCKER_IMAGE }}",
))


@tutor_hooks.Filters.COMPOSE_MOUNTS.add()
def _mount_frontend_apps(volumes, name):
Expand All @@ -82,27 +81,7 @@ def _mount_frontend_apps(volumes, name):
return volumes


@tutor_hooks.Filters.IMAGES_PULL.add()
@tutor_hooks.Filters.IMAGES_PUSH.add()
def _add_remote_mfe_image_iff_customized(images, user_config):
"""
Register MFE image for pushing & pulling if and only if it has
been set to something other than the default.
This is work-around to an upstream issue with MFE config. Briefly:
User config is baked into MFE builds, so Tutor cannot host a generic
pre-built MFE image. Howevever, individual Tutor users may want/need to
build and host their own MFE image. So, as a compromise, we tell Tutor
to push/pull the MFE image if the user has customized it to anything
other than the default image URL.
"""
image_tag = user_config["MFE_DOCKER_IMAGE"]
if not image_tag.startswith("docker.io/overhangio/openedx-mfe:"):
# Image has been customized. Add to list for pulling/pushing.
images.append(("mfe", image_tag))
return images

####### Boilerplate code
# Boilerplate code
# Add the "templates" folder as a template root
tutor_hooks.Filters.ENV_TEMPLATE_ROOTS.add_item(
pkg_resources.resource_filename("tutormfe", "templates")
Expand All @@ -122,7 +101,13 @@ def _add_remote_mfe_image_iff_customized(images, user_config):
)
):
with open(path, encoding="utf-8") as patch_file:
tutor_hooks.Filters.ENV_PATCHES.add_item((os.path.basename(path), patch_file.read()))
# Here we force tutor-mfe lms patches to be loaded first, thus ensuring when opreators override
# MFE_CONFIG and/or MFE_CONFIG_OVERRIDES, their patches will be loaded after this plugin's
patch_name = os.path.basename(path)
priority = priorities.HIGH if patch_name in \
['openedx-lms-production-settings', 'openedx-lms-development-settings'] \
else priorities.DEFAULT
tutor_hooks.Filters.ENV_PATCHES.add_item((patch_name, patch_file.read()), priority=priority)

# Add configuration entries
tutor_hooks.Filters.CONFIG_DEFAULTS.add_items(
Expand Down
3 changes: 3 additions & 0 deletions tutormfe/templates/mfe/apps/mfe/webpack.dev-tutor.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ module.exports = merge(baseDevConfig, {
// We will have to make changes to thix config in later releases of webpack dev devServer
// https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md
allowedHosts: 'all',
proxy: {
'/api/mfe_config/v1' : 'http://{{ LMS_HOST }}:8000',
}
},
})

Expand Down
35 changes: 9 additions & 26 deletions tutormfe/templates/mfe/build/mfe/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,43 +51,26 @@ RUN npm clean-install --no-audit --no-fund --registry=$NPM_REGISTRY \
{{ patch("mfe-dockerfile-post-npm-install") }}
COPY --from={{ app["name"] }}-src /openedx/app /openedx/app
COPY --from={{ app["name"] }}-i18n /openedx/app/src/i18n/messages /openedx/app/src/i18n/messages
ENV PUBLIC_PATH='/{{ app["name"] }}/'
EXPOSE {{ app['port'] }}

COPY ./env/production /openedx/env/production
{%- set overrides = app.get("env", {}).get("production", {}) %}
{%- if overrides %}
RUN echo "setting production overrides..." \
{%- for key, value in app.get("env", {}).get("production", {}).items() %}
&& echo "{{ key }}='{{ value }}'" >> /openedx/env/production \
{%- endfor %}
&& echo "done setting production overrides"
{%- endif %}
# configuration needed at build time
ENV APP_ID={{ app["name"] }}
ENV PUBLIC_PATH='/{{ app["name"] }}/'
ENV MFE_CONFIG_API_URL=/api/mfe_config/v1
ARG ENABLE_NEW_RELIC=false

######## {{ app["name"] }} (dev)
FROM {{ app["name"] }}-common AS {{ app["name"] }}-dev
COPY ./env/development /openedx/env/development
{%- set overrides = app.get("env", {}).get("development", {}) %}
{%- if overrides %}
RUN echo "setting development overrides..." \
{%- for key, value in overrides.items() %}
&& echo "{{ key }}='{{ value }}'" >> /openedx/env/development \
{%- endfor %}
&& echo "done setting development overrides"
{%- endif %}
CMD ["/bin/bash", "-c", "set -a && \
source /openedx/env/production && \
source /openedx/env/development && \
npm run start --- --config ./webpack.dev-tutor.config.js"]
ENV NODE_ENV=development
CMD ["/bin/bash", "-c", "npm run start --- --config ./webpack.dev-tutor.config.js"]
{% endfor %}

# Production images are last to accelerate dev image building
{%- for app in iter_values_named(suffix="MFE_APP") %}
######## {{ app["name"] }} (production)
FROM {{ app["name"] }}-common AS {{ app["name"] }}-prod
RUN bash -c "set -a && \
source /openedx/env/production && \
npm run build"
ENV NODE_ENV=production
RUN npm run build
{% endfor %}

####### final production image with all static assets
Expand Down
12 changes: 0 additions & 12 deletions tutormfe/templates/mfe/build/mfe/env/development

This file was deleted.

26 changes: 0 additions & 26 deletions tutormfe/templates/mfe/build/mfe/env/production

This file was deleted.

0 comments on commit 9ad9263

Please sign in to comment.