diff --git a/src/bridge/secrets/xpro/secrets.ci.yaml b/src/bridge/secrets/xpro/secrets.ci.yaml index 208e7623c..287024208 100644 --- a/src/bridge/secrets/xpro/secrets.ci.yaml +++ b/src/bridge/secrets/xpro/secrets.ci.yaml @@ -15,6 +15,7 @@ django: secret-key: ENC[AES256_GCM,data:IR8mDRxJofjn24SnW6X4iL6zEkRQR4RnJnbwFCCivk6JgU2fE08/Guj6,iv:kszWMVm+bM246ccOS14bi62vKZYwycEumxATbLd5X9s=,tag:utebSWJj3XzjXi6ZJEeVag==,type:str] status-token: ENC[AES256_GCM,data:4TqN9+3NIW6EkIZP1WW0Nozu368By/seLIlf1Ohhk5K4FaiFYt4ZTCbe,iv:dQYEp5I2iD1RdXUHxRHwDd4fxMJB1AHVA1yxtMe+pSo=,tag:VT2qTNG4AMnTifybyQP5KQ==,type:str] google-sheets: + admin_emails: ENC[AES256_GCM,data:rlas+Q==,iv:c7b+PHNmjxLuSVIW1ECcLfRX5YuRtSjBMZY6DLYvMzQ=,tag:eWg+TIBEk4olGYh1zU4JUQ==,type:str] deferral_worksheet_id: ENC[AES256_GCM,data:AnrTuyfb5/eS,iv:DpQQ6S0A8/zLKOzNOY790/a4ISkml14NMlOxrgZNns0=,tag:/nBw4FxLAZXw8WmmxfffeA==,type:int] drive_shared_id: ENC[AES256_GCM,data:HDFJhap2imd0BPN6Vfl3P5aZng==,iv:hAzcbfDZMky/kOOsdxAkU7ihpl9S0EeJGTd6jQGqQyk=,tag:Iu+izXNax0T2tqiayQhqHA==,type:str] enroll_change_sheet_id: ENC[AES256_GCM,data:yjsSnPoeZd7q/PBmQHGf0ArYHCNjEPmURrs34gkqOMAlnOJIvTbmDYmcz84=,iv:bFew26R1tNjdUZv0ahIBepxOsstTmyKPu9d47qzDOUk=,tag:V0JYxTXkVJr8kejGi642AQ==,type:str] @@ -70,8 +71,8 @@ sops: created_at: "2024-01-24T19:58:50Z" enc: vault:v1:eqLTbBnjlosTlLhitEaYfHOchh7o8OmbMOOtXWnQ7aOBeoI3dZri5XxotBFe+8J97mDuWsP+p0a3tCiN age: [] - lastmodified: "2023-11-21T20:37:23Z" - mac: ENC[AES256_GCM,data:O3BS3awTlMblER4c16MfH5e0ExcafLQPRRqQEb0qGZYbAoqhWv2BTufeaxwJEtxu3SZ8VkOBGQL/AfBnLfEFT9SnkyfmSPVgUQmFu33aNgE5jsYZMBoJKXLAUcpQwwgnOsJ08AYepK386qa2EuNY+4R60SqcRWKlfqGEVd526JI=,iv:JTgpbaE3K7sISa650/IJisi6I+ZgLtOdKwyivN9GMEE=,tag:5GKjSP74GeNoBcthGiD+CA==,type:str] + lastmodified: "2024-01-25T16:21:01Z" + mac: ENC[AES256_GCM,data:JT+3IqzJpJXqZxmLF7eKkaZK/CroN8YzKFnIfeOGIvXSRGR9fO4eDpAjn/BxxbfecoSWlWRdKgE1oTQJElHX362cpGMgVYjjKzgd4mHwj8Ovie4Uhg7rq1iHa9t/ZHnILpC1Ddr9CLemayMIOxTN5cdhu3+bg4O1RAKLkL7zT4s=,iv:DJRvL7KHKl7jEzubRoh3y6JeXn05kK8se9PWKQ8iaeg=,tag:ZibUAITBxC1589Wbbd/aSg==,type:str] pgp: - created_at: "2024-01-24T19:58:50Z" enc: |- diff --git a/src/bridge/secrets/xpro/secrets.production.yaml b/src/bridge/secrets/xpro/secrets.production.yaml index 091640776..c00450aa4 100644 --- a/src/bridge/secrets/xpro/secrets.production.yaml +++ b/src/bridge/secrets/xpro/secrets.production.yaml @@ -15,6 +15,7 @@ django: secret-key: ENC[AES256_GCM,data:2DIOAoTTkCwrb/gC0pKzj65VX0ebswT+y9ZR8CowolhP4AdlYjor8uV1,iv:R5cTUIdGvIeBw1NNSenl3hBh0BK7UDKiNWaXjBWxG1U=,tag:1gZFpxwDaVZ35PZGJFxT7g==,type:str] status-token: ENC[AES256_GCM,data:6cXIg+ROcd8syfG4DloUg2qzPII3dBCMaGUKvKDICz2oZkwySu/6JQlO,iv:cseg4byKbiWRxHvAA5kXG5nIQufiDFokt9NAqcaZ3zA=,tag:sqtBHCujqKMFWBYnxG8bCg==,type:str] google-sheets: + admin_emails: ENC[AES256_GCM,data:HOmpSoB4rucki1TkJ5xdLe3jh4+Z6xMuCY0vFMNPqlL5Bl8xxXWsle54b4Mk0d6bLvpT1jA0gfNxhFseJFKYSRLB1DOZJy5ZLLnIIV+wQZpPihxl8diAjGrYlr9yMcqSM8SZsAoVCtksPtodZMVrWhim2qYAWDBU/3GjPbegco/+j9/ztWdfstaKBmMR6MnbeFavpgCJ4Na7fOdWOJPrKnZzNtomFg22ObmKwGjsgvUPExAJQgMoSrMUfiBT5lOrKCB4ygKpYR9gfaOcwF4GOluXe1KLyrj7b8PF+sEpdpJ3JpKxmrCEljuJqVo8PoZ3pWKT8DGncx9xrVfReS/bi5O+H7A9J1l2wmB0W3pBUX+4qxBDDBQspmCcNd2UvU4pppGeHXIH,iv:4Y+8FgOPHSusuKb8QfxdAe5tp5NBAnFksLtVfGClFzo=,tag:blutJAd+D6Xs4+y2y3e4TA==,type:str] deferral_worksheet_id: ENC[AES256_GCM,data:amxvArjdNukohQ==,iv:6s0YO1nBu6ZGz4+SATs25QmxKlzxlaK793skZ674ww4=,tag:sBjL4iXmV6kKasvceB5fIQ==,type:int] drive_shared_id: enroll_change_sheet_id: ENC[AES256_GCM,data:gW67IqZvXDbRk07ArUzImd8GNn0Y8ZE/NWA6e2dKrHb8i+/5C5Z2SlJi9I8=,iv:W2KD12+f26kXxQ+K444QNmyrBuZS7ianY/y68h7bdSk=,tag:HUzhnOD5WpdeneJ24l73VA==,type:str] @@ -70,8 +71,8 @@ sops: created_at: "2024-01-24T20:22:29Z" enc: vault:v1:RPwGIhH3XI6PuKWF10YLU93NnxzMG03C4s8keU3UdKVoxhTnQNfGxSLNGjpl6A3r7J4PpgqouLv1MyJG age: [] - lastmodified: "2024-01-03T17:57:39Z" - mac: ENC[AES256_GCM,data:+r5xBoffEoItIYhoYQluotHDhrJkYUnd8IRuIqiBqcJEIuINmqfMcU8yJDX2c1bCOxzLhsNDUhU2w1t7Yf87TymYHZ/eGPJM8sxnhyULF9Mi5dV5d13nriNgJ3Lnbyuo5kr7rMThxCL+ZpwGPt4c4aDmsGE8vNw1jMo6wewma8I=,iv:7YkpMaKwb09NEFZPyeoSdZoA5L+2UVyXrFHxw3nUD4s=,tag:ozbxwnBk5+hX6AiAXPngwg==,type:str] + lastmodified: "2024-01-25T16:23:49Z" + mac: ENC[AES256_GCM,data:7Z+vRq/hsrMmA01hxisH11030o5hEPATc3olZPLdJSqYLEMyoWT3/3s56SVCIxiKRoLl5LE84VmR+yS1BmAxiiAM36V4xN1KCz9o1jmKtJN8mxUAqBiOcvEnTzKSEqf0DzgZ0GVP7dI5rZzD/K8+p062J4EY3TeGv2dfyzLvrOA=,iv:TA0QyX51MeVAyISStFzuRKKLUQ7QDZCIMmc1Zvc7M18=,tag:JopBEH1R3BVYj8o+UmfseA==,type:str] pgp: - created_at: "2024-01-24T20:22:29Z" enc: |- diff --git a/src/bridge/secrets/xpro/secrets.qa.yaml b/src/bridge/secrets/xpro/secrets.qa.yaml index 58bacdd3f..31bf97e00 100644 --- a/src/bridge/secrets/xpro/secrets.qa.yaml +++ b/src/bridge/secrets/xpro/secrets.qa.yaml @@ -15,6 +15,7 @@ django: secret-key: ENC[AES256_GCM,data:EzQsA3DJ3U1BYMkZGHX6tzdQ75j4tV8uiYLHd0HOhl2D2ofuhHnM4uaJ,iv:SIrrEANJ6tYIWcZP/QbH2pv21wzpmkZvuUlifxaiwkY=,tag:PoNYJGiJQrCKFVT9UPv7Ng==,type:str] status-token: ENC[AES256_GCM,data:5Y2AhgPC1OrOLT2mjw+Gv0G/z7kcKhJK4Mb8a0WOAbjTgkFxJRebZvrF,iv:hGp+yKs4wLAPq/7lM/5+4q9C1XFitgOnewGXWPTvE8I=,tag:ihi/6KPPFNAz//y5TVNgCg==,type:str] google-sheets: + admin_emails: ENC[AES256_GCM,data:T4xA9lFS9hYyU2w/cQg+16Eyadi2bwhi4zpd7CiTBg1dXrABm8BcK3HNODcsagsXPQ4R5gZoRg3iCbeh,iv:9o83An92q9r/P+KvQAmVvxM8NJnu09tGTR6OTNkvBgM=,tag:Cr+oZIbQQ6n3xu7JPA7rbA==,type:str] deferral_worksheet_id: ENC[AES256_GCM,data:2gjUHM3QiAsO,iv:f2IRy0nNU9/YATiWyIkTpFceECnHEtP/dqyK0VsUdqc=,tag:tH3uALnyTJTU063lh1bPKA==,type:int] drive_shared_id: ENC[AES256_GCM,data:uTPNV1spMxC5DbEUU2zpgxokQQ==,iv:R6oz7GXmzCjtk6S99MJliq4EO02VQKO2Y+XChIz5o2M=,tag:a/2kBk5k23U+4YfBaXg3DA==,type:str] enroll_change_sheet_id: ENC[AES256_GCM,data:I9Q0laFZ2sD2e2DFimZOagSoWWbnlUqAfuIpfKM+kT72kOrwPAjcC5gvzNM=,iv:+Vxmcp4GUuCx5ftPJ07PQkd25xGFmePmWMrm59so43k=,tag:hbCUhDJcP1QtnCfL/6P5Pg==,type:str] @@ -70,8 +71,8 @@ sops: created_at: "2024-01-24T20:20:19Z" enc: vault:v1:4YxP4nojlHbL45TdbZ73pGe7XfQrCbwLoN2bDeq5qO6Roj4waUZzrwhAVGAQfuw0T7XUAJbHkeblG01t age: [] - lastmodified: "2023-11-20T23:42:17Z" - mac: ENC[AES256_GCM,data:ZY/xRmab/YH5mwAu5ceJ+aMIfsGG+DyHTISgp8W6bOB4qaHpSAC+2ITMmH1wIGwD9YvovzsmvT8uC51pP1WxwcTBovrvyuFrJLNxtYs6tb7BHm9SHktTgAgS/KuzDIdO5Fn+FyGCdOg6+PaiYK+pxxllCZIc5p6M9lxQW/35gGA=,iv:LsIdi1+GFeN7w1ZtolLYxRUzGUnvmxDq3WjGR+LlDz0=,tag:k0TgIYvkxLaNo5/tdvR92w==,type:str] + lastmodified: "2024-01-25T16:21:28Z" + mac: ENC[AES256_GCM,data:eVLV+tt6s+0mncXBwwmrhKckOLeR+0htLhDj2KPItbnQ8XASp4Bez4HIX/fTYVbC1q7L4BpKbrxWwTwpHJri5n8pXhK6YfJdjjEYfCQW2koxFL7f1B16Gi5KZ59o87dpf2UA0MWt64jouZatgPJWhLm+3uuvykKZFGG/H4rHFK0=,iv:aQdxsVr0Bc9/LpudsVPmg7VVJrfe/TMTE52Xdbe8QMg=,tag:7crlTPfz1KCOkyCVQmavog==,type:str] pgp: - created_at: "2024-01-24T20:20:19Z" enc: |- diff --git a/src/ol_concourse/pipelines/infrastructure/xpro/__init__.py b/src/ol_concourse/pipelines/infrastructure/xpro/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/ol_concourse/pipelines/infrastructure/xpro/pipeline.py b/src/ol_concourse/pipelines/infrastructure/xpro/pipeline.py new file mode 100644 index 000000000..2933d4487 --- /dev/null +++ b/src/ol_concourse/pipelines/infrastructure/xpro/pipeline.py @@ -0,0 +1,44 @@ +from ol_concourse.lib.jobs.infrastructure import pulumi_jobs_chain +from ol_concourse.lib.models.fragment import PipelineFragment +from ol_concourse.lib.models.pipeline import Identifier, Pipeline +from ol_concourse.lib.resources import git_repo +from ol_concourse.pipelines.constants import PULUMI_CODE_PATH + +xpro_pulumi_code = git_repo( + name=Identifier("ol-infrastructure-pulumi-xpro"), + uri="https://github.com/mitodl/ol-infrastructure", + branch="main", + paths=[ + "src/ol_infrastructure/applications/xpro/", + "src/ol_infrastructure/lib/", + "src/bridge/lib/", + "src/bridge/secrets/xpro", + ], +) + +pulumi_jobs = pulumi_jobs_chain( + pulumi_code=xpro_pulumi_code, + stack_names=[ + "applications.xpro.CI", + "applications.xpro.QA", + "applications.xpro.Production", + ], + project_name="ol-infrastructure-xpro-application", + project_source_path=PULUMI_CODE_PATH.joinpath("applications/xpro/"), +) + +mm_fragment = PipelineFragment.combine_fragments(pulumi_jobs) +xpro_pipeline = Pipeline( + resources=[*mm_fragment.resources, xpro_pulumi_code], + resource_types=mm_fragment.resource_types, + jobs=mm_fragment.jobs, +) + +if __name__ == "__main__": + import sys + + with open("definition.json", "w") as definition: # noqa: PTH123 + definition.write(xpro_pipeline.json(indent=2)) + sys.stdout.write(xpro_pipeline.json(indent=2)) + sys.stdout.write("\n") + sys.stdout.write("fly -t pr-inf set-pipeline -p pulumi-xpro -c definition.json") diff --git a/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.CI.yaml b/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.CI.yaml index b9dbc373e..8d23664bd 100644 --- a/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.CI.yaml +++ b/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.CI.yaml @@ -2,6 +2,37 @@ secretsprovider: awskms://alias/infrastructure-secrets-ci encryptedkey: AQICAHjnbqe9AmEW1Js10nySybyuAG7Fb5E9EHUgkmqFDv7PxQGajxbkewesj3PCq3IiGvEkAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMLdJMjR0tj3iBnE3zAgEQgDuyIU42lpmTEO6PIHEU1dyNeIx0UiVTdoUqn4nXWcCOsqlRNWM1o7CyByuiATE23j7d9AIOhwEZxCRvew== config: + heroku:app_id: + secure: v1:d1JeftBc68QcCrCH:tQV5P2EU4H/eF7jMjUied4fIcj2Q6d9ujnhvfn5oxJiPbh41oVff6sWQDs9SUl65gQOTWg== + heroku:user: "mitx-devops" + heroku_app:vars: + CYBERSOURCE_SECURE_ACCEPTANCE_URL: "https://testsecureacceptance.cybersource.com/pay" + CYBERSOURCE_WSDL_URL: "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.154.wsdl" + DIGITAL_CREDENTIALS_SUPPORTED_RUNS: "" + GA_TRACKING_ID: "UA-5145472-40" + GTM_TRACKING_ID: "GTM-KJHRV6K" + HUBSPOT_ENTERPRISE_PAGE_FORM_ID: "de779fe5-c777-4da5-847b-ed2efc39e987" + HUBSPOT_FOOTER_FORM_GUID: "3ab7232f-13e3-43b6-aa6a-305f92208109" + HUBSPOT_NEW_COURSES_FORM_GUID: "0c3a6036-a8b2-4de7-80a7-1e409322a6aa" + HUBSPOT_PORTAL_ID: 23128026 + LOGOUT_REDIRECT_URL: "https://courses-ci.xpro.mit.edu/logout" + MAILGUN_FROM_EMAIL: "MIT xPRO " + MAILGUN_SENDER_DOMAIN: "xpro-ci-mail.odl.mit.edu" + MITOL_HUBSPOT_API_ID_PREFIX: "xpro-ci" + MITXPRO_BASE_URL: "https://xpro-ci.odl.mit.edu" + MITXPRO_LOG_LEVEL: "INFO" + MITXPRO_SECURE_SSL_HOST: "xpro-ci.odl.mit.edu" + OPENEDX_API_BASE_URL: "https://courses-ci.xpro.mit.edu" + SENTRY_LOG_LEVEL: "ERROR" + SHEETS_DEFERRAL_FIRST_ROW: 184 + SHEETS_MONITORING_FREQUENCY: 86400 + SHEETS_REFUND_COMPLETED_DATE_COL: 12 + SHEETS_REFUND_ERROR_COL: 13 + SHEETS_REFUND_FIRST_ROW: 254 + SHEETS_REFUND_PROCESSOR_COL: 11 + SHEETS_REFUND_SKIP_ROW_COL: 14 + VOUCHER_COMPANY_ID: 1 + ZENDESK_DOMAIN_VERIFICATION_TAG_VALUE: "o0itxdfh369m1bw4cuz9" vault:address: https://vault-ci.odl.mit.edu vault_server:env_namespace: operations.ci xpro:db_password: diff --git a/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.Production.yaml b/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.Production.yaml index ccc372199..934731372 100644 --- a/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.Production.yaml +++ b/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.Production.yaml @@ -2,6 +2,51 @@ secretsprovider: awskms://alias/infrastructure-secrets-production encryptedkey: AQICAHiiGjYUolrtj8PCnScLM7oLAdMl8nJrLjQjnqyl1LykYgFDjLJKJAYAWev29dCBcDyuAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMieA4m88ozKuQi3iTAgEQgDuiRRn7fmtTU/I9yXx3ere67Ee32cTL8gbh3JraHuColZVV3FPJZl+ScIjcV7egqP4I+0RidtZhM0t2VA== config: + heroku:app_id: + secure: v1:sflDJ1/1qixNMWt8:zni8/Aoc3kXrp6nBAU2oTyCcCcHrQl/yLYswzg49KlQlrg07oB4FoV/4Fr6PsCcTZ39ttw== + heroku:user: "mitx-devops" + heroku_app:vars: + CSRF_TRUSTED_ORIGINS: "xpro.mit.edu,xpro-web.odl.mit.edu" + CYBERSOURCE_SECURE_ACCEPTANCE_URL: "https://secureacceptance.cybersource.com/pay" + CYBERSOURCE_WSDL_URL: "https://ics2wsa.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.154.wsdl" + DRIVE_WEBHOOK_EXPIRATION_MINUTES: 1440 + DRIVE_WEBHOOK_RENEWAL_PERIOD_MINUTES: 720 + FEATURE_ENABLE_ENTERPRISE: "False" + GA_TRACKING_ID: "UA-5145472-38" + GTM_TRACKING_ID: "GTM-KG4FR7J" + HUBSPOT_CREATE_USER_FORM_ID: "9ada5d38-33ee-415c-8cb2-9d72e735b1d5" + HUBSPOT_ENTERPRISE_PAGE_FORM_ID: "7863854e-029b-4604-9097-009e86fd1d5f" + HUBSPOT_FOOTER_FORM_GUID: "6f7e46ec-f757-43a4-b109-597210df0f75" + HUBSPOT_ID_PREFIX: "xpro" + HUBSPOT_NEW_COURSES_FORM_GUID: "ad5d54e5-5ca9-4255-9c17-fa222e0a9b82" + HUBSPOT_PORTAL_ID: 4994459 + LOGOUT_REDIRECT_URL: "https://courses.xpro.mit.edu/logout" + MAILGUN_FROM_EMAIL: "MIT xPRO " + MAILGUN_SENDER_DOMAIN: "xpro.mit.edu" + MITOL_HUBSPOT_API_ID_PREFIX: "xpro" + MITXPRO_BASE_URL: "https://xpro.mit.edu" + MITXPRO_LOG_LEVEL: "INFO" + MITXPRO_SECURE_SSL_HOST: "xpro.mit.edu" + MITXPRO_USE_S3: "True" + OPENEDX_API_BASE_URL: "https://courses.xpro.mit.edu" + SENTRY_LOG_LEVEL: "WARN" + SHEETS_DEFERRAL_FIRST_ROW: 234 + SHEETS_MONITORING_FREQUENCY: 3600 + SHEETS_REFUND_COMPLETED_DATE_COL: 13 + SHEETS_REFUND_ERROR_COL: 14 + SHEETS_REFUND_FIRST_ROW: 287 + SHEETS_REFUND_PROCESSOR_COL: 12 + SHEETS_REFUND_SKIP_ROW_COL: 15 + UWSGI_IGNORE_WRITE_ERRORS: "True" + UWSGI_MAX_REQUESTS: 2000 + UWSGI_WORKERS: 3 + UWSGI_RELOAD_ON_RSS: 300 + UWSGI_THREADS: 25 + VOUCHER_COMPANY_ID: 4 + #WAGTAIL_CACHE_MAX_ENTRIES: 500 + #YOUTUBE_FETCH_SCHEDULE_SECONDS: 7200 + ZENDESK_DOMAIN_VERIFICATION_TAG_VALUE: "o0itxdfh369m1bw4cuz9" + ZENDESK_HELP_WIDGET_ENABLED: "True" vault:address: https://vault-production.odl.mit.edu vault_server:env_namespace: operations.production xpro:db_password: diff --git a/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.QA.yaml b/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.QA.yaml index d03f91ea1..6397bc3b7 100644 --- a/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.QA.yaml +++ b/src/ol_infrastructure/applications/xpro/Pulumi.applications.xpro.QA.yaml @@ -2,6 +2,50 @@ secretsprovider: awskms://alias/infrastructure-secrets-qa encryptedkey: AQICAHg42pDDDGBhpaX14TdtzcK1hbiMYTHsYRH4k5GL5RFpIwGkmvWWRjGZVEsaIcDCbAAnAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM0nzLkwr0lwKzMM8uAgEQgDs4M/ioh+ijwiVK9fQ5KTN+GvChiAKQYBUwBv5RQwr5kB6SLAD4cf7YjK+mCjUbHnxvG4veumZkiRGWmw== config: + heroku:app_id: + secure: v1:CwgCINZqs7rxJOiU:xMp2xgeZd+tGV/v10GRE0fJ7Snuwah5tHbKh2ojO3mbTjBhjI77Gqd6PyvUIBe/H8R8DxQ== + heroku:user: "mitx-devops" + heroku_app:vars: + CSRF_TRUSTED_ORIGINS: "rc.xpro.mit.edu,xpro-rc.odl.mit.edu" + CYBERSOURCE_SECURE_ACCEPTANCE_URL: "https://testsecureacceptance.cybersource.com/pay" + CYBERSOURCE_WSDL_URL: "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.154.wsdl" + DIGITAL_CREDENTIALS_SUPPORTED_RUNS: "course-v1:xPRO+TestCourse1+R2,course-v1:xPRO+TestCourse2+R2,program-v1:xPRO+TestProgram" + GA_TRACKING_ID: "UA-5145472-40" + GTM_TRACKING_ID: "GTM-KJHRV6K" + HUBSPOT_ENTERPRISE_PAGE_FORM_ID: "de779fe5-c777-4da5-847b-ed2efc39e987" + HUBSPOT_FOOTER_FORM_GUID: "3ab7232f-13e3-43b6-aa6a-305f92208109" + HUBSPOT_ID_PREFIX: "xpro-rc" + HUBSPOT_NEW_COURSES_FORM_GUID: "0c3a6036-a8b2-4de7-80a7-1e409322a6aa" + HUBSPOT_PORTAL_ID: 23128026 + LOGOUT_REDIRECT_URL: "https://courses-rc.xpro.mit.edu/logout" + MAILGUN_FROM_EMAIL: "MIT xPRO " + MAILGUN_SENDER_DOMAIN: "xpro-rc-mail.odl.mit.edu" + MITOL_HUBSPOT_API_ID_PREFIX: "xpro-rc" + MITXPRO_BASE_URL: "https://rc.xpro.mit.edu" + MITXPRO_LOG_LEVEL: "INFO" + MITXPRO_SECURE_SSL_HOST: "rc.xpro.mit.edu" + MITXPRO_USE_S3: "True" + OPENEDX_API_BASE_URL: "https://courses-rc.xpro.mit.edu" + SENTRY_LOG_LEVEL: "ERROR" + SHEETS_DEFERRAL_FIRST_ROW: 184 + SHEETS_MONITORING_FREQUENCY: 43200 + SHEETS_REFUND_COMPLETED_DATE_COL: 13 + SHEETS_REFUND_ERROR_COL: 14 + SHEETS_REFUND_FIRST_ROW: 254 + SHEETS_REFUND_PROCESSOR_COL: 12 + SHEETS_REFUND_SKIP_ROW_COL: 15 + UWSGI_IGNORE_WRITE_ERRORS: "True" + UWSGI_LISTEN: 500 + UWSGI_MAX_REQUESTS: 2000 + UWSGI_PROCESSES: 3 + UWSGI_RELOAD_ON_RSS: 300 + UWSGI_THREADS: 25 + UWSGI_WORKER_RELOAD_MERCY: 60 + VOUCHER_COMPANY_ID: 1 + WAGTAIL_CACHE_MAX_ENTRIES: 500 + YOUTUBE_FETCH_SCHEDULE_SECONDS: 7200 + ZENDESK_DOMAIN_VERIFICATION_TAG_VALUE: "o0itxdfh369m1bw4cuz9" + ZENDESK_HELP_WIDGET_ENABLED: "True" vault:address: https://vault-qa.odl.mit.edu vault_server:env_namespace: operations.qa xpro:db_password: diff --git a/src/ol_infrastructure/applications/xpro/__main__.py b/src/ol_infrastructure/applications/xpro/__main__.py index e919345c9..a24b3eba5 100644 --- a/src/ol_infrastructure/applications/xpro/__main__.py +++ b/src/ol_infrastructure/applications/xpro/__main__.py @@ -9,9 +9,10 @@ from pathlib import Path import pulumi_vault as vault +import pulumiverse_heroku as heroku from bridge.lib.magic_numbers import DEFAULT_POSTGRES_PORT from bridge.secrets.sops import read_yaml_secrets -from pulumi import Config, StackReference, export +from pulumi import Config, InvokeOptions, StackReference, export from pulumi_aws import ec2, iam, s3 from ol_infrastructure.components.aws.database import OLAmazonDB, OLPostgresDBConfig @@ -20,14 +21,20 @@ OLVaultPostgresDatabaseConfig, ) from ol_infrastructure.lib.aws.iam_helper import lint_iam_policy +from ol_infrastructure.lib.heroku import setup_heroku_provider from ol_infrastructure.lib.ol_types import AWSBase from ol_infrastructure.lib.pulumi_helper import parse_stack from ol_infrastructure.lib.stack_defaults import defaults from ol_infrastructure.lib.vault import setup_vault_provider if Config("vault_server").get("env_namespace"): - setup_vault_provider() + setup_vault_provider(skip_child_token=True) +setup_heroku_provider() + xpro_config = Config("xpro") +heroku_config = Config("heroku") +heroku_app_config = Config("heroku_app") + stack_info = parse_stack() network_stack = StackReference(f"infrastructure.aws.network.{stack_info.name}") apps_vpc = network_stack.require_output("applications_vpc") @@ -216,6 +223,180 @@ data_json=json.dumps(data), ) +# Heroku App configuration +# env_name is 'ci' 'rc' or 'production' +env_name = stack_info.name.lower() if stack_info.name != "QA" else "rc" + +# Values that are generally unchanging across environments +heroku_vars = { + "AWS_STORAGE_BUCKET_NAME": xpro_storage_bucket_name, + "CRON_COURSERUN_SYNC_HOURS": "*", + "CYBERSOURCE_MERCHANT_ID": "mit_odl_xpro", + "CYBERSOURCE_REFERENCE_PREFIX": f"xpro-{env_name}", + "CERTIFICATE_CREATION_DELAY_IN_HOURS": 48, + "ENABLE_ORDER_RECEIPTS": "True", + "FEATURE_COUPON_SHEETS": "True", + "FEATURE_COUPON_SHEETS_TRACK_REQUESTER": "True", + "FEATURE_COURSE_DROPDOWN": "True", + "FEATURE_WEBINARS": "True", + "FEATURE_ENABLE_BLOG": "True", + "FEATURE_ENABLE_TAXES_DISPLAY": "True", + "HUBSPOT_PIPELINE_ID": "75e28846-ad0d-4be2-a027-5e1da6590b98", + "MITOL_DIGITAL_CREDENTIALS_AUTH_TYPE": "code", + "MITOL_DIGITAL_CREDENTIALS_DEEP_LINK_URL": "dccrequest://request", + "MITXPRO_ADMIN_EMAIL": "cuddle-bunnies@mit.edu", + "MITXPRO_DB_CONN_MAX_AGE": 0, + "MITXPRO_DB_DISABLE_SSL": "True", + "MITXPRO_EMAIL_TLS": "True", + "MITXPRO_ENVIRONMENT": env_name, + "MITXPRO_FROM_EMAIL": "MIT xPRO ", + "MITXPRO_OAUTH_PROVIDER": "mitxpro-oauth2", + "MITXPRO_REPLY_TO_ADDRESS": "MIT xPRO ", + "MITXPRO_SECURE_SSL_REDIRECT": "True", + "MITXPRO_USE_S3": "True", + "NODE_MODULES_CACHE": "False", + "OAUTH2_PROVIDER_ALLOWED_REDIRECT_URI_SCHEMES": "http,https,dccrequest", + # This can be removed once PR#1314 is in production, + "OPENEDX_OAUTH_APP_NAME": "edx-oauth-app", + # This replaces OPENEDX_GRADES_API_TOKEN and is + # tied to xpro-grades-api user in openedx, + "OPENEDX_SERVICE_WORKER_USERNAME": "xpro-service-worker-api", + "PGBOUNCER_DEFAULT_POOL_SIZE": 50, + "PGBOUNCER_MIN_POOL_SIZE": 5, + "SHEETS_DATE_TIMEZONE": "America/New_York", + "SHEETS_TASK_OFFSET": "120", + "SHOW_UNREDEEMED_COUPON_ON_DASHBOARD": "True", + "SITE_NAME": "MIT xPRO", + "USE_X_FORWARDED_HOST": "True", +} + +# Combine var source above with values explictly defined in pulumi configuration file +heroku_vars.update(**heroku_app_config.get_object("vars")) + +# Finally, populate a map of vars that contain secrets +auth_aws_mitx_creds_xpro_app = vault.generic.get_secret_output( + path="aws-mitx/creds/xpro-app", + with_lease_start_time=False, + opts=InvokeOptions(parent=xpro_vault_backend_role), +) +auth_postgres_xpro_creds_app = vault.generic.get_secret_output( + path="postgres-xpro/creds/app", + with_lease_start_time=False, + opts=InvokeOptions(parent=xpro_vault_backend_role), +) +secret_operations_global_mailgun_api_key = vault.generic.get_secret_output( + path="secret-operations/global/mailgun-api-key", + opts=InvokeOptions(parent=xpro_vault_backend_role), +) + +sensitive_heroku_vars = { + # Secrets that can be source locally from SOPS + "COUPON_REQUEST_SHEET_ID": xpro_vault_secrets["google-sheets"]["sheet_id"], + "CYBERSOURCE_ACCESS_KEY": xpro_vault_secrets["cybersource"]["access_key"], + "CYBERSOURCE_INQUIRY_LOG_NACL_ENCRYPTION_KEY": xpro_vault_secrets["cybersource"][ + "inquiry_log_nacl_encryption_key" + ], + "CYBERSOURCE_PROFILE_ID": xpro_vault_secrets["cybersource"]["profile_id"], + "CYBERSOURCE_SECURITY_KEY": xpro_vault_secrets["cybersource"]["security_key"], + "CYBERSOURCE_TRANSACTION_KEY": xpro_vault_secrets["cybersource"]["transaction_key"], + "DEFERRAL_REQUEST_WORKSHEET_ID": xpro_vault_secrets["google-sheets"][ + "deferral_worksheet_id" + ], + "DIGITAL_CREDENTIALS_ISSUER_ID": xpro_vault_secrets["digital-credentials"][ + "issuer_id" + ], + "DIGITAL_CREDENTIALS_OAUTH2_CLIENT_ID": xpro_vault_secrets["digital-credentials"][ + "oauth2_client_id" + ], + "DIGITAL_CREDENTIALS_VERIFICATION_METHOD": xpro_vault_secrets[ + "digital-credentials" + ]["verification_method"], + "DRIVE_OUTPUT_FOLDER_ID": xpro_vault_secrets["google-sheets"]["folder_id"], + "DRIVE_SERVICE_ACCOUNT_CREDS": xpro_vault_secrets["google-sheets"][ + "service_account_creds" + ], + "DRIVE_SHARED_ID": xpro_vault_secrets["google-sheets"]["drive_shared_id"], + "ENROLLMENT_CHANGE_SHEET_ID": xpro_vault_secrets["google-sheets"][ + "enroll_change_sheet_id" + ], + "HIREFIRE_TOKEN": xpro_vault_secrets["hirefire"]["token"], + "MITOL_DIGITAL_CREDENTIALS_HMAC_SECRET": xpro_vault_secrets["digital-credentials"][ + "hmac_secret" + ], + "MITOL_DIGITAL_CREDENTIALS_VERIFY_SERVICE_BASE_URL": xpro_vault_secrets[ + "digital-credentials" + ]["sign_and_verify_url"], + "MITOL_HUBSPOT_API_PRIVATE_TOKEN": xpro_vault_secrets["hubspot"][ + "api_private_token" + ], + "MITXPRO_EMAIL_HOST": xpro_vault_secrets["smtp"]["relay_host"], + "MITXPRO_EMAIL_PASSWORD": xpro_vault_secrets["smtp"]["relay_password"], + "MITXPRO_EMAIL_PORT": xpro_vault_secrets["smtp"]["relay_port"], + "MITXPRO_EMAIL_USER": xpro_vault_secrets["smtp"]["relay_username"], + "MITXPRO_REGISTRATION_ACCESS_TOKEN": xpro_vault_secrets["openedx"][ + "registration_access_token" + ], + "MITXPRO_SUPPORT_EMAIL": xpro_vault_secrets["smtp"]["support_email"], + "OPENEDX_API_CLIENT_ID": xpro_vault_secrets["openedx-api-client"]["client_id"], + "OPENEDX_API_CLIENT_SECRET": xpro_vault_secrets["openedx-api-client"][ + "client_secret" + ], + "OPENEDX_API_KEY": xpro_vault_secrets["openedx"]["edxapp_api_key"], + "OPENEDX_GRADES_API_TOKEN": xpro_vault_secrets["openedx"]["grades_api_token"], + "OPENEDX_SERVICE_WORKER_API_TOKEN": xpro_vault_secrets["openedx"][ + "service_worker_api_token" + ], + "RECAPTCHA_SECRET_KEY": xpro_vault_secrets["recaptcha"]["secret_key"], + "RECAPTCHA_SITE_KEY": xpro_vault_secrets["recaptcha"]["site_key"], + "REFUND_REQUEST_WORKSHEET_ID": xpro_vault_secrets["google-sheets"][ + "refund_worksheet_id" + ], + "SECRET_KEY": xpro_vault_secrets["django"]["secret-key"], + "SENTRY_DSN": xpro_vault_secrets["sentry"]["dsn"], + "SHEETS_ADMIN_EMAILS": xpro_vault_secrets["google-sheets"]["admin_emails"], + "STATUS_TOKEN": xpro_vault_secrets["django"]["status-token"], + "VOUCHER_DOMESTIC_AMOUNT_KEY": xpro_vault_secrets["voucher-domestic"]["amount_key"], + "VOUCHER_DOMESTIC_COURSE_KEY": xpro_vault_secrets["voucher-domestic"]["course_key"], + "VOUCHER_DOMESTIC_CREDITS_KEY": xpro_vault_secrets["voucher-domestic"][ + "credits_key" + ], + "VOUCHER_DOMESTIC_DATES_KEY": xpro_vault_secrets["voucher-domestic"]["dates_key"], + "VOUCHER_DOMESTIC_DATE_KEY": xpro_vault_secrets["voucher-domestic"]["date_key"], + "VOUCHER_DOMESTIC_EMPLOYEE_ID_KEY": xpro_vault_secrets["voucher-domestic"][ + "employee_id_key" + ], + "VOUCHER_DOMESTIC_EMPLOYEE_KEY": xpro_vault_secrets["voucher-domestic"][ + "employee_key" + ], + "VOUCHER_DOMESTIC_KEY": xpro_vault_secrets["voucher-domestic"]["key"], + # Auth secrets that require something more involved + "AWS_ACCESS_KEY_ID": auth_aws_mitx_creds_xpro_app.data.apply( + lambda data: "{}".format(data["access_key"]) + ), + "AWS_SECRET_ACCESS_KEY": auth_aws_mitx_creds_xpro_app.data.apply( + lambda data: "{}".format(data["secret_key"]) + ), + "DATABASE_URL": auth_postgres_xpro_creds_app.data.apply( + lambda data: "postgres://{}:{}@xpro-db-applications-{}.cbnm7ajau6mi.us-east-1.rds.amazonaws.com:5432/xpro".format( + data["username"], data["password"], stack_info.name.lower() + ) + ), + # Static secrets that require something more involved + "MAILGUN_KEY": secret_operations_global_mailgun_api_key.data.apply( + lambda data: "{}".format(data["value"]) + ), +} + + +# Put it all together into a ConfigAssociation resource +heroku_app_id = heroku_config.require("app_id") +xpro_heroku_configassociation = heroku.app.ConfigAssociation( + f"xpro-{stack_info.env_suffix}-heroku-configassociation", + app_id=heroku_app_id, + sensitive_vars=sensitive_heroku_vars, + vars=heroku_vars, +) + export( "xpro_app", {