From a644a2a4468621f5f539202430582d54d21765df Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Wed, 3 Apr 2024 14:51:12 +0800 Subject: [PATCH 01/22] [FIX] argocd_deployer - Removed deployment directory from parameters. It's now in the master application set. --- argocd_deployer/README.rst | 4 -- argocd_deployer/data/application_set.xml | 2 +- .../data/ir_config_parameter_data.xml | 28 +++----- argocd_deployer/models/application_set.py | 70 +++++++++---------- argocd_deployer/tests/test_application_set.py | 65 +++++------------ 5 files changed, 61 insertions(+), 108 deletions(-) diff --git a/argocd_deployer/README.rst b/argocd_deployer/README.rst index 5188c07..b2dade5 100644 --- a/argocd_deployer/README.rst +++ b/argocd_deployer/README.rst @@ -19,10 +19,6 @@ System parameters ----------------- The following system parameters can be configured. -- ``argocd.application_set_repo``: Set to the SSH URL of the repository that stores the application sets. -- ``argocd.application_set_branch``: Set to the branch that contains the application sets. Should normally be HEAD or main. -- ``argocd.application_set_repo_directory``: The local folder that contains the .git folder of the repository that contains the application sets. -- ``argocd.application_set_deployment_directory``: The folder inside the repository that will contain the application sets. - ``argocd.git_simulation_mode``: For debugging purposes. Can be set to values like ``none``, ``push``, ``pull``, ``push&pull``. By setting one of these values, the corresponding git action will be skipped. This can prevent delays and repo clogging when doing manual tests. diff --git a/argocd_deployer/data/application_set.xml b/argocd_deployer/data/application_set.xml index fe6edda..7ad8646 100644 --- a/argocd_deployer/data/application_set.xml +++ b/argocd_deployer/data/application_set.xml @@ -6,7 +6,7 @@ git@github.com:onesteinbv/flavoured-odoo-k8s.git main /home/tarteo/repo - + application_sets True diff --git a/argocd_deployer/data/ir_config_parameter_data.xml b/argocd_deployer/data/ir_config_parameter_data.xml index 54a8a4e..9be549f 100644 --- a/argocd_deployer/data/ir_config_parameter_data.xml +++ b/argocd_deployer/data/ir_config_parameter_data.xml @@ -1,25 +1,5 @@ - - argocd.application_set_repo - git@github.com:onesteinbv/odoo-generator-k8s.git - - - argocd.application_set_branch - main - - - argocd.application_set_repo_directory - /home/tarteo/repo - - - argocd.application_set_deployment_directory - application_sets - - - argocd.master_application_set_directory - application_set_deployment/templates - argocd.application_set_destruction_delay 3600 @@ -28,4 +8,12 @@ argocd.application_destruction_delay 60 + + argocd.git_simulation_mode + none + + + argocd.allow_immediate_deployment + False + diff --git a/argocd_deployer/models/application_set.py b/argocd_deployer/models/application_set.py index 78ed251..c1ecf78 100644 --- a/argocd_deployer/models/application_set.py +++ b/argocd_deployer/models/application_set.py @@ -71,16 +71,11 @@ class ApplicationSet(models.Model): @api.constrains("deployment_directory") def _check_deployment_directory(self): - if not self.is_master: - if not self.deployment_directory: - raise ValidationError("Deployment directory is required.") - if self.deployment_directory[-1] == "/": - raise ValidationError("Deployment directories should not end with '/'.") - else: - if self.deployment_directory: - raise ValidationError( - "The master deployment directory should be empty." - ) + if not self.deployment_directory: + raise ValidationError("Deployment directory is required.") + if self.deployment_directory[-1] == "/": + raise ValidationError("Deployment directories should not end with '/'.") + @api.constrains("is_master") def _check_is_master_deployment(self): @@ -123,60 +118,63 @@ def _create_path_or_error(path, directory_name, path_does_not_exist_action): @api.model def _get_master_repository_directory(self, path_does_not_exist_action="create"): - get_param = self.env["ir.config_parameter"].get_param + master = self.env.ref("argocd_deployer.application_set_master") path = os.path.join( - get_param("argocd.application_set_repo_directory", ""), - get_param("argocd.application_set_branch", "master"), + master.repository_directory, + master.branch, ) self._create_path_or_error( path, "Master repository directory", path_does_not_exist_action ) return path + @api.model def _get_master_deployment_directory(self, path_does_not_exist_action="create"): """Return the directory the master application set lives.""" - get_param = self.env["ir.config_parameter"].get_param + master = self.env.ref("argocd_deployer.application_set_master") path = os.path.join( self._get_master_repository_directory(path_does_not_exist_action), - get_param("argocd.master_application_set_directory", ""), + master.deployment_directory, ) self._create_path_or_error( path, "Master deployment directory", path_does_not_exist_action ) return path - def _get_application_set_deployment_directory( + def _get_application_set_repository_directory( self, path_does_not_exist_action="create" ): - """Return the directory in which all application sets live.""" - get_param = self.env["ir.config_parameter"].get_param + """Return the directory in which the applications in the current application + set are located.""" + self.ensure_one() path = os.path.join( - self._get_master_repository_directory(path_does_not_exist_action), - get_param("argocd.application_set_deployment_directory", ""), - self.name, + self.repository_directory, + self.branch, ) self._create_path_or_error( - path, "Application set deployment directory", path_does_not_exist_action + path, "Application set directory", path_does_not_exist_action ) return path - def _get_application_set_repository_directory( + def _get_application_set_deployment_directory( self, path_does_not_exist_action="create" ): - """Return the directory in which the applications in the current application - set are located.""" + """Return the directory in which all application sets live.""" + self.ensure_one() path = os.path.join( - self.repository_directory, - self.branch, + self._get_application_set_repository_directory(path_does_not_exist_action), + self.deployment_directory, + self.name, ) self._create_path_or_error( - path, "Application set directory", path_does_not_exist_action + path, "Application set deployment directory", path_does_not_exist_action ) return path def _get_application_deployment_directory( self, application_name, path_does_not_exist_action="create" ): + self.ensure_one() path = os.path.join( self._get_application_set_repository_directory(path_does_not_exist_action), self.deployment_directory, @@ -190,7 +188,7 @@ def _get_application_deployment_directory( def _compute_is_deployed(self): for app_set in self: if app_set.is_master: - path = app_set._get_master_deployment_directory() + path = app_set._get_master_deployment_directory("ignore") else: path = app_set._get_application_set_deployment_directory("ignore") path = os.path.join( @@ -248,16 +246,14 @@ def _format_commit_message(self, message): return message % self.name def _get_argocd_template(self): - get_param = self.env["ir.config_parameter"].get_param + master = self.env.ref("argocd_deployer.application_set_master") replacements = { - "{{.config.repository_url}}": get_param("argocd.application_set_repo", "") - or "", - "{{.config.branch}}": get_param("argocd.application_set_branch", "master") - or "", - "{{.config.deployment_directory}}": get_param( - "argocd.application_set_deployment_directory", "application_sets" - ) + "{{.config.repository_url}}": master.repository_url or "" or "", + "{{.config.branch}}": master.branch or "main", + "{{.config.deployment_directory}}": ( + master.deployment_directory or "application_sets" + ), "{{.application_set.name}}": self.name or "", "{{.application_set.repository_url}}": self.repository_url or "", "{{.application_set.branch}}": self.branch or "", diff --git a/argocd_deployer/tests/test_application_set.py b/argocd_deployer/tests/test_application_set.py index 2e9bdf7..c1f0e89 100644 --- a/argocd_deployer/tests/test_application_set.py +++ b/argocd_deployer/tests/test_application_set.py @@ -40,57 +40,43 @@ def setUpClass(cls): } ) + cls.master_application_set = cls.env.ref("argocd_deployer.application_set_master") + cls.default_application_set = cls.env.ref("argocd_deployer.application_set_default") cls.templated_yaml = f""" apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: - repoURL: {cls.env.ref("argocd_deployer.application_set_repo").value} - revision: {cls.env.ref("argocd_deployer.application_set_branch").value} - path: {cls.env.ref("argocd_deployer.application_set_deployment_directory").value} + repoURL: {cls.master_application_set.repository_url} + revision: {cls.master_application_set.branch} + path: {cls.master_application_set.deployment_directory} template-path: {{{{.path.path}}}} """ def test_get_master_repository_directory(self): """The master repository directory is stored in the config. Check that it behaves.""" - self.env["ir.config_parameter"].set_param( - "argocd.application_set_repo_directory", "/home/nonexistent/directory" - ) - master_path = os.path.join( - self.env["ir.config_parameter"].get_param( - "argocd.application_set_repo_directory" - ), - self.env["ir.config_parameter"].get_param("argocd.application_set_branch"), - ) + master = self.env.ref("argocd_deployer.application_set_master") + master.repository_directory = "/home/test" + master.deployment_directory = "application_sets" with patch("os.makedirs") as mkdirs: self.application_set._get_master_repository_directory() - mkdirs.assert_called_with(master_path, mode=0o775) - self.application_set.repository_directory = "/this_directory_does_not_exist/" + mkdirs.assert_called_with("/home/test/main", mode=0o775) with self.assertRaisesRegex(UserError, "Master repository directory"): self.application_set._get_master_repository_directory("error") def test_master_deployment_directory(self): """The master deployment directory is the folder inside the master repository master application set lives. It's specified in the config.""" - self.env["ir.config_parameter"].set_param( - "argocd.application_set_repo_directory", "/home/nonexistent/directory" - ) - master_deployment_path = os.path.join( - self.env["ir.config_parameter"].get_param( - "argocd.application_set_repo_directory" - ), - self.env["ir.config_parameter"].get_param("argocd.application_set_branch"), - self.env["ir.config_parameter"].get_param( - "argocd.master_application_set_directory" - ), - ) + master = self.env.ref("argocd_deployer.application_set_master") + master.repository_directory = "/home/test" + master.deployment_directory = "application_sets" with patch("os.makedirs") as mkdirs: - self.application_set._get_master_deployment_directory() - mkdirs.assert_called_with(master_deployment_path, mode=0o775) + self.env["argocd.application.set"]._get_master_deployment_directory() + mkdirs.assert_called_with("/home/test/main/application_sets", mode=0o775) self.application_set.deployment_directory = "/this_directory_does_not_exist" with patch( f"{APPLICATION_SET_PATCH}._get_master_repository_directory", - return_value=master_deployment_path, + return_value="/home/test", ): with self.assertRaisesRegex(UserError, "Master deployment directory"): self.application_set._get_master_deployment_directory("error") @@ -98,26 +84,13 @@ def test_master_deployment_directory(self): def test_get_application_set_deployment_directory(self): """The application set deployment directory is folder inside the master repository where the application sets live. It's specified in the config.""" - self.env["ir.config_parameter"].set_param( - "argocd.application_set_repo_directory", "/home/nonexistent/directory" - ) - master_deployment_path = os.path.join( - self.env["ir.config_parameter"].get_param( - "argocd.application_set_repo_directory" - ), - self.env["ir.config_parameter"].get_param("argocd.application_set_branch"), - self.env["ir.config_parameter"].get_param( - "argocd.application_set_deployment_directory" - ), - self.application_set.name, - ) + with patch("os.makedirs") as mkdirs: self.application_set._get_application_set_deployment_directory() - mkdirs.assert_called_with(master_deployment_path, mode=0o775) - self.application_set.deployment_directory = "/this_directory_does_not_exist" + mkdirs.assert_called_with("/home/test/Olive/instances/test-set", mode=0o775) with patch( - f"{APPLICATION_SET_PATCH}._get_master_repository_directory", - return_value=master_deployment_path, + f"{APPLICATION_SET_PATCH}._get_application_set_repository_directory", + return_value="/home/nonexistent/directory", ): with self.assertRaisesRegex( UserError, "Application set deployment directory" From 4f382c95b34cb0b53f1c9fe2fa85f5aa6cac6e3e Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Wed, 3 Apr 2024 15:20:05 +0800 Subject: [PATCH 02/22] [FIX] argocd_deployer - Pre-commit --- argocd_deployer/models/application_set.py | 4 +--- argocd_deployer/tests/test_application_set.py | 9 ++++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/argocd_deployer/models/application_set.py b/argocd_deployer/models/application_set.py index c1ecf78..9d0afd3 100644 --- a/argocd_deployer/models/application_set.py +++ b/argocd_deployer/models/application_set.py @@ -76,7 +76,6 @@ def _check_deployment_directory(self): if self.deployment_directory[-1] == "/": raise ValidationError("Deployment directories should not end with '/'.") - @api.constrains("is_master") def _check_is_master_deployment(self): if not self.is_master: @@ -248,8 +247,7 @@ def _format_commit_message(self, message): def _get_argocd_template(self): master = self.env.ref("argocd_deployer.application_set_master") replacements = { - "{{.config.repository_url}}": master.repository_url or "" - or "", + "{{.config.repository_url}}": master.repository_url or "" or "", "{{.config.branch}}": master.branch or "main", "{{.config.deployment_directory}}": ( master.deployment_directory or "application_sets" diff --git a/argocd_deployer/tests/test_application_set.py b/argocd_deployer/tests/test_application_set.py index c1f0e89..416f6ec 100644 --- a/argocd_deployer/tests/test_application_set.py +++ b/argocd_deployer/tests/test_application_set.py @@ -1,4 +1,3 @@ -import os from unittest.mock import MagicMock, mock_open, patch from odoo.exceptions import UserError @@ -40,8 +39,12 @@ def setUpClass(cls): } ) - cls.master_application_set = cls.env.ref("argocd_deployer.application_set_master") - cls.default_application_set = cls.env.ref("argocd_deployer.application_set_default") + cls.master_application_set = cls.env.ref( + "argocd_deployer.application_set_master" + ) + cls.default_application_set = cls.env.ref( + "argocd_deployer.application_set_default" + ) cls.templated_yaml = f""" apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet From c5e2ca977ee1c347a875bc8827ca663910d3bfbd Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Wed, 3 Apr 2024 15:45:41 +0800 Subject: [PATCH 03/22] [FIX] argocd_deployer - Small fix to deployment directory. --- argocd_deployer/models/application_set.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/argocd_deployer/models/application_set.py b/argocd_deployer/models/application_set.py index 9d0afd3..608d6e0 100644 --- a/argocd_deployer/models/application_set.py +++ b/argocd_deployer/models/application_set.py @@ -161,8 +161,7 @@ def _get_application_set_deployment_directory( """Return the directory in which all application sets live.""" self.ensure_one() path = os.path.join( - self._get_application_set_repository_directory(path_does_not_exist_action), - self.deployment_directory, + self._get_master_deployment_directory(path_does_not_exist_action), self.name, ) self._create_path_or_error( @@ -187,7 +186,7 @@ def _get_application_deployment_directory( def _compute_is_deployed(self): for app_set in self: if app_set.is_master: - path = app_set._get_master_deployment_directory("ignore") + path = app_set._get_master_repository_directory("ignore") else: path = app_set._get_application_set_deployment_directory("ignore") path = os.path.join( @@ -266,8 +265,7 @@ def _get_argocd_template(self): def _create_master_application_set(self): self.ensure_one() template_yaml = self._get_argocd_template() - deployment_directory = self._get_master_deployment_directory("create") - application_set_dir = deployment_directory + application_set_dir = self._get_master_repository_directory("create") yaml_file = os.path.join(application_set_dir, "application_set.yaml") message = "Added application set `%s`." with open(yaml_file, "w") as fh: From f5673099f42efafa188e91f124e64d819dc1d1e9 Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Wed, 3 Apr 2024 15:48:49 +0800 Subject: [PATCH 04/22] [FIX] argocd_deployer - Fix tests. --- argocd_deployer/tests/test_application_set.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/argocd_deployer/tests/test_application_set.py b/argocd_deployer/tests/test_application_set.py index 416f6ec..e5b2189 100644 --- a/argocd_deployer/tests/test_application_set.py +++ b/argocd_deployer/tests/test_application_set.py @@ -87,12 +87,14 @@ def test_master_deployment_directory(self): def test_get_application_set_deployment_directory(self): """The application set deployment directory is folder inside the master repository where the application sets live. It's specified in the config.""" - + master = self.env.ref("argocd_deployer.application_set_master") + master.repository_directory = "/home/test" + master.branch = "Olive" with patch("os.makedirs") as mkdirs: self.application_set._get_application_set_deployment_directory() - mkdirs.assert_called_with("/home/test/Olive/instances/test-set", mode=0o775) + mkdirs.assert_called_with("/home/test/Olive/application_sets/test-set", mode=0o775) with patch( - f"{APPLICATION_SET_PATCH}._get_application_set_repository_directory", + f"{APPLICATION_SET_PATCH}._get_master_deployment_directory", return_value="/home/nonexistent/directory", ): with self.assertRaisesRegex( @@ -138,7 +140,7 @@ def test_create_application_set(self): with patch("os.makedirs") as mock_makedir: with patch("os.path.join", return_value="joined/path"): files, message = self.application_set._create_application_set() - self.assertEqual(3, mock_makedir.call_count) + self.assertEqual(4, mock_makedir.call_count) mock_makedir.assert_called_with("joined/path") m.assert_called_once_with("joined/path", "w") m().write.assert_called_once() From 5dccd33abb4fc7f5e31fa6a5b014fdca8ea39973 Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Wed, 3 Apr 2024 15:50:30 +0800 Subject: [PATCH 05/22] [FIX] argocd_deployer - Pre-commit again --- argocd_deployer/tests/test_application_set.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/argocd_deployer/tests/test_application_set.py b/argocd_deployer/tests/test_application_set.py index e5b2189..7c7f21a 100644 --- a/argocd_deployer/tests/test_application_set.py +++ b/argocd_deployer/tests/test_application_set.py @@ -92,7 +92,9 @@ def test_get_application_set_deployment_directory(self): master.branch = "Olive" with patch("os.makedirs") as mkdirs: self.application_set._get_application_set_deployment_directory() - mkdirs.assert_called_with("/home/test/Olive/application_sets/test-set", mode=0o775) + mkdirs.assert_called_with( + "/home/test/Olive/application_sets/test-set", mode=0o775 + ) with patch( f"{APPLICATION_SET_PATCH}._get_master_deployment_directory", return_value="/home/nonexistent/directory", From 612ca7e26dd67addb2713dd6e75e7141bf12a0da Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Wed, 3 Apr 2024 17:51:58 +0800 Subject: [PATCH 06/22] [FIX] argocd_deployer - Pre-commit again --- argocd_deployer/models/application_set.py | 28 +++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/argocd_deployer/models/application_set.py b/argocd_deployer/models/application_set.py index 608d6e0..37a27f3 100644 --- a/argocd_deployer/models/application_set.py +++ b/argocd_deployer/models/application_set.py @@ -187,6 +187,7 @@ def _compute_is_deployed(self): for app_set in self: if app_set.is_master: path = app_set._get_master_repository_directory("ignore") + path = os.path.join(path, "master_application_set/templates") else: path = app_set._get_application_set_deployment_directory("ignore") path = os.path.join( @@ -263,15 +264,23 @@ def _get_argocd_template(self): return template_yaml def _create_master_application_set(self): + """The master application set will be deployed in a master_application_set folder + in the root of the repository. There will be a templates folder in it, and a + Chart.yaml file.""" self.ensure_one() template_yaml = self._get_argocd_template() - application_set_dir = self._get_master_repository_directory("create") - yaml_file = os.path.join(application_set_dir, "application_set.yaml") + repo_dir = self._get_master_repository_directory("create") + application_set_dir = os.path.join(repo_dir, "master_application_set") + template_dir = os.path.join(application_set_dir, "templates") + if not os.path.exists(template_dir): + os.makedirs(template_dir) message = "Added application set `%s`." + + yaml_file = os.path.join(template_dir, "application_set.yaml") with open(yaml_file, "w") as fh: fh.write(template_yaml) - chart_file = os.path.join(application_set_dir, "..", "Chart.yaml") + chart_file = os.path.join(application_set_dir, "Chart.yaml") with open(chart_file, "w") as fh: fh.write( f"""apiVersion: v2 @@ -300,14 +309,15 @@ def _create_application_set(self): def _remove_master_application_set(self): """Remove an application set for ArgoCD.""" self.ensure_one() - deployment_directory = self._get_master_deployment_directory("error") + repo_dir = self._get_master_repository_directory("error") + application_set_dir = os.path.join(repo_dir, "master_application_set") + template_dir = os.path.join(application_set_dir, "templates") message = "Removed application set `%s`." - application_set_dir = deployment_directory - yaml_file = os.path.join(application_set_dir, "application_set.yaml") + yaml_file = os.path.join(template_dir, "application_set.yaml") + chart_file = os.path.join(application_set_dir, "Chart.yaml") + os.remove(chart_file) os.remove(yaml_file) - if not self.is_master: - os.removedirs(application_set_dir) - chart_file = os.path.join(application_set_dir, "..", "Chart.yaml") + os.removedirs(template_dir) return {REMOVE_FILES: [yaml_file, chart_file]}, message From ab82e8210b904f5122d9bbb1299a4b9f7a845fdc Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Wed, 3 Apr 2024 18:17:01 +0800 Subject: [PATCH 07/22] [FIX] argocd_deployer - Fix config --- argocd_deployer/data/ir_config_parameter_data.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/argocd_deployer/data/ir_config_parameter_data.xml b/argocd_deployer/data/ir_config_parameter_data.xml index 9be549f..efc3d9e 100644 --- a/argocd_deployer/data/ir_config_parameter_data.xml +++ b/argocd_deployer/data/ir_config_parameter_data.xml @@ -14,6 +14,6 @@ argocd.allow_immediate_deployment - False + From f97e897fbcfff6f3448a99bd4ad43739ec59bc08 Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Thu, 4 Apr 2024 15:41:24 +0800 Subject: [PATCH 08/22] [FIX] argocd_deployer - Fixed templates and application set deployment --- .../data/application_set_template.xml | 19 ++++++++++--------- argocd_deployer/models/application_set.py | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/argocd_deployer/data/application_set_template.xml b/argocd_deployer/data/application_set_template.xml index 49b50a5..575f5ba 100644 --- a/argocd_deployer/data/application_set_template.xml +++ b/argocd_deployer/data/application_set_template.xml @@ -2,30 +2,31 @@ Master application set template - Do not change apiVersion: argoproj.io/v1alpha1 +apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: - name: curq-application-sets + name: curq-master-application-set namespace: argocd spec: goTemplate: true generators: - - git: - repoURL: {{.config.repository_url}} - revision: {{.config.branch}} - files: - - path: {{.config.deployment_directory}} + - git: + repoURL: {{.config.repository_url}} + revision: {{.config.branch}} + files: + - path: {{.config.deployment_directory}}/**/application_set.yaml template: metadata: - name: curq-application-sets + name: "application-set-{{ "{{ " }}.path.basename{{ " }}" }}" spec: project: "default" source: repoURL: {{.config.repository_url}} targetRevision: {{.config.branch}} - path: {{.config.deployment_directory}}/{{ "{{ " }}.path.basename{{ " }}" }} + path: "{{ "{{ " }}.path.filename{{ " }}" }}" destination: name: in-cluster - namespace: argocd + namespace: "application-set-{{ "{{ " }}.path.basename{{ " }}" }}" syncPolicy: syncOptions: - CreateNamespace=true diff --git a/argocd_deployer/models/application_set.py b/argocd_deployer/models/application_set.py index 37a27f3..390d88f 100644 --- a/argocd_deployer/models/application_set.py +++ b/argocd_deployer/models/application_set.py @@ -239,7 +239,7 @@ def _get_repository(self): return Repo.clone_from(self.repository_url, directory) def _get_branch(self): - return self.branch + return self.env.ref("argocd_deployer.application_set_master").branch def _format_commit_message(self, message): return message % self.name From 425671ff4c37a7b28cca9c8d22bb4200927cfb38 Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Thu, 4 Apr 2024 21:09:03 +0800 Subject: [PATCH 09/22] [IMP] It's now possible to set the application set in the product form. --- argocd_sale/views/product_template.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/argocd_sale/views/product_template.xml b/argocd_sale/views/product_template.xml index 59bc760..613b78e 100644 --- a/argocd_sale/views/product_template.xml +++ b/argocd_sale/views/product_template.xml @@ -10,6 +10,7 @@ These fields are used to create an ArgoCD application after the invoice is paid.

+ From c040e22f21a155df5295672282c2c2216dd676ee Mon Sep 17 00:00:00 2001 From: Mark Schuit Date: Tue, 9 Apr 2024 13:21:39 +0800 Subject: [PATCH 10/22] [FIX] Domain now looked up in global, not globals --- argocd_deployer/models/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/argocd_deployer/models/application.py b/argocd_deployer/models/application.py index bb63b0b..0f87a13 100644 --- a/argocd_deployer/models/application.py +++ b/argocd_deployer/models/application.py @@ -110,7 +110,7 @@ def _render_description(self): @staticmethod def _get_domain(helm): - return helm.get("domain") or helm.get("globals", {}).get("domain") + return helm.get("domain") or helm.get("global", {}).get("domain") def get_urls(self): self.ensure_one() From 3a4df2088ee5c22f774b2047c17c7ab008788492 Mon Sep 17 00:00:00 2001 From: Arne De Geeter Date: Wed, 28 Feb 2024 14:47:01 +0100 Subject: [PATCH 11/22] start changes --- gitlab/__manifest__.py | 1 + membership_activity/__manifest__.py | 1 + membership_activity_cde/__manifest__.py | 1 + membership_activity_github/__manifest__.py | 1 + membership_activity_gitlab/__manifest__.py | 1 + membership_activity_project_type/__manifest__.py | 1 + 6 files changed, 6 insertions(+) diff --git a/gitlab/__manifest__.py b/gitlab/__manifest__.py index b63985a..a783be6 100644 --- a/gitlab/__manifest__.py +++ b/gitlab/__manifest__.py @@ -4,6 +4,7 @@ "version": "16.0.1.0.0", "author": "Onestein", "website": "https://www.onestein.nl", + "license": "AGPL-3", "depends": ["base"], "external_dependencies": {"python": ["gitlab"]}, "data": ["security/ir_model_access.xml", "views/gitlab_view.xml", "menuitems.xml"], diff --git a/membership_activity/__manifest__.py b/membership_activity/__manifest__.py index ba2f6df..e54b59c 100644 --- a/membership_activity/__manifest__.py +++ b/membership_activity/__manifest__.py @@ -5,6 +5,7 @@ "version": "16.0.1.0.0", "author": "Onestein", "website": "https://www.onestein.nl", + "license": "AGPL-3", "depends": ["membership", "project"], "data": [ "security/ir_model_access.xml", diff --git a/membership_activity_cde/__manifest__.py b/membership_activity_cde/__manifest__.py index a1e410a..c866d25 100644 --- a/membership_activity_cde/__manifest__.py +++ b/membership_activity_cde/__manifest__.py @@ -5,6 +5,7 @@ "version": "16.0.1.0.0", "author": "Onestein", "website": "https://www.onestein.nl", + "license": "AGPL-3", "depends": ["membership_activity"], "data": [ "data/membership_activity_type_data.xml", diff --git a/membership_activity_github/__manifest__.py b/membership_activity_github/__manifest__.py index 7b152c0..6ec4835 100644 --- a/membership_activity_github/__manifest__.py +++ b/membership_activity_github/__manifest__.py @@ -4,6 +4,7 @@ "version": "16.0.1.0.0", "author": "Onestein", "website": "https://www.onestein.nl", + "license": "AGPL-3", "depends": ["membership_activity", "membership_activity_cde", "queue_job"], "external_dependencies": {"python": ["github"]}, "data": [ diff --git a/membership_activity_gitlab/__manifest__.py b/membership_activity_gitlab/__manifest__.py index 43d740d..f4a81f1 100644 --- a/membership_activity_gitlab/__manifest__.py +++ b/membership_activity_gitlab/__manifest__.py @@ -4,6 +4,7 @@ "version": "16.0.1.0.0", "author": "Onestein", "website": "https://www.onestein.nl", + "license": "AGPL-3", "depends": [ "membership_activity", "membership_activity_cde", diff --git a/membership_activity_project_type/__manifest__.py b/membership_activity_project_type/__manifest__.py index 2cd31ed..d0865fb 100644 --- a/membership_activity_project_type/__manifest__.py +++ b/membership_activity_project_type/__manifest__.py @@ -5,6 +5,7 @@ "version": "16.0.1.0.0", "author": "Onestein", "website": "https://www.onestein.nl", + "license": "AGPL-3", "depends": ["membership_activity", "project_type"], "auto_install": True, "data": [ From 0b9396b3bdda112c1c31b500c1f4792c2a6483d2 Mon Sep 17 00:00:00 2001 From: Arne De Geeter Date: Wed, 28 Feb 2024 17:12:34 +0100 Subject: [PATCH 12/22] warning check --- website_membership_registration/models/membership_section.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website_membership_registration/models/membership_section.py b/website_membership_registration/models/membership_section.py index 5811cfe..d3a1211 100644 --- a/website_membership_registration/models/membership_section.py +++ b/website_membership_registration/models/membership_section.py @@ -8,16 +8,19 @@ class MembershipSection(models.Model): string="# of Following Members", compute="_compute_partner_ids", store=True, + compute_sudo=False, ) applicant_partner_count = fields.Integer( string="# of Applicant Members", compute="_compute_partner_ids", store=True, + compute_sudo=False, ) collaborator_partner_count = fields.Integer( string="# of Collaborating Members", compute="_compute_partner_ids", store=True, + compute_sudo=False, ) @api.depends( From d79b2375a323fc03a2498000525a1753932cb166 Mon Sep 17 00:00:00 2001 From: Anjeel Haria Date: Fri, 12 Apr 2024 19:09:46 +0530 Subject: [PATCH 13/22] [ADD] Added modules website_payment_recurring_donations and website_payment_recurring_donations_mollie --- .../__init__.py | 2 + .../__manifest__.py | 23 +++ .../controllers/__init__.py | 4 + .../controllers/portal.py | 59 +++++++ .../data/donation_data.xml | 21 +++ .../i18n/nl.po | 86 ++++++++++ .../models/__init__.py | 1 + .../models/payment_transaction.py | 29 ++++ .../static/src/js/website_payment_form.js | 15 ++ .../static/src/snippets/s_donation/000.js | 18 +++ .../static/src/snippets/s_donation/000.scss | 16 ++ .../views/donation_templates.xml | 33 ++++ .../views/payment_transaction_view.xml | 37 +++++ .../views/res_partner_view.xml | 17 ++ .../views/snippets/s_donation.xml | 40 +++++ .../__init__.py | 1 + .../__manifest__.py | 17 ++ .../i18n/nl.po | 33 ++++ .../models/__init__.py | 3 + .../models/payment_provider.py | 29 ++++ .../models/payment_transaction.py | 148 ++++++++++++++++++ .../models/res_partner.py | 10 ++ .../views/res_partner_view.xml | 17 ++ 23 files changed, 659 insertions(+) create mode 100755 website_payment_recurring_donations/__init__.py create mode 100755 website_payment_recurring_donations/__manifest__.py create mode 100755 website_payment_recurring_donations/controllers/__init__.py create mode 100755 website_payment_recurring_donations/controllers/portal.py create mode 100755 website_payment_recurring_donations/data/donation_data.xml create mode 100755 website_payment_recurring_donations/i18n/nl.po create mode 100755 website_payment_recurring_donations/models/__init__.py create mode 100755 website_payment_recurring_donations/models/payment_transaction.py create mode 100755 website_payment_recurring_donations/static/src/js/website_payment_form.js create mode 100755 website_payment_recurring_donations/static/src/snippets/s_donation/000.js create mode 100755 website_payment_recurring_donations/static/src/snippets/s_donation/000.scss create mode 100755 website_payment_recurring_donations/views/donation_templates.xml create mode 100755 website_payment_recurring_donations/views/payment_transaction_view.xml create mode 100755 website_payment_recurring_donations/views/res_partner_view.xml create mode 100755 website_payment_recurring_donations/views/snippets/s_donation.xml create mode 100755 website_payment_recurring_donations_mollie/__init__.py create mode 100755 website_payment_recurring_donations_mollie/__manifest__.py create mode 100755 website_payment_recurring_donations_mollie/i18n/nl.po create mode 100755 website_payment_recurring_donations_mollie/models/__init__.py create mode 100755 website_payment_recurring_donations_mollie/models/payment_provider.py create mode 100755 website_payment_recurring_donations_mollie/models/payment_transaction.py create mode 100755 website_payment_recurring_donations_mollie/models/res_partner.py create mode 100755 website_payment_recurring_donations_mollie/views/res_partner_view.xml diff --git a/website_payment_recurring_donations/__init__.py b/website_payment_recurring_donations/__init__.py new file mode 100755 index 0000000..19240f4 --- /dev/null +++ b/website_payment_recurring_donations/__init__.py @@ -0,0 +1,2 @@ +from . import controllers +from . import models \ No newline at end of file diff --git a/website_payment_recurring_donations/__manifest__.py b/website_payment_recurring_donations/__manifest__.py new file mode 100755 index 0000000..f24f21d --- /dev/null +++ b/website_payment_recurring_donations/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2023 Onestein- Anjeel Haria +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +{ + 'name': 'Recurring donations', + 'version': '16.0.1.0.0', + 'category': 'Website', + 'license': 'LGPL-3', + 'summary': 'Recurring donations', + 'description': """Recurring donations""", + 'depends': ["website_payment"], + 'data': [ + "data/donation_data.xml", + "views/snippets/s_donation.xml", + "views/donation_templates.xml", + "views/payment_transaction_view.xml", + "views/res_partner_view.xml" + ], + "assets": { + 'web.assets_frontend': [ + 'website_payment_recurring_donations/static/src/js/website_payment_form.js', + ], + }, +} diff --git a/website_payment_recurring_donations/controllers/__init__.py b/website_payment_recurring_donations/controllers/__init__.py new file mode 100755 index 0000000..825b563 --- /dev/null +++ b/website_payment_recurring_donations/controllers/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2023 Onestein - Anjeel Haria +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import portal diff --git a/website_payment_recurring_donations/controllers/portal.py b/website_payment_recurring_donations/controllers/portal.py new file mode 100755 index 0000000..5019d63 --- /dev/null +++ b/website_payment_recurring_donations/controllers/portal.py @@ -0,0 +1,59 @@ +# Copyright 2023 Onestein - Anjeel Haria +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.addons.payment.controllers import portal as payment_portal +from odoo import http +from odoo.http import request + + +class PaymentPortal(payment_portal.PaymentPortal): + + @http.route('/donation/transaction/', type='json', auth='public', website=True, sitemap=False) + def donation_transaction(self, amount, currency_id, partner_id, access_token, minimum_amount=0, **kwargs): + if request.env.user._is_public(): + kwargs['donation_partner_details'] = kwargs['partner_details'] + return super().donation_transaction(amount, currency_id, partner_id, access_token, minimum_amount, **kwargs) + + def _get_custom_rendering_context_values( + self, + donation_options=None, + donation_descriptions=None, + is_donation=False, + **kwargs + ): + rendering_context = super()._get_custom_rendering_context_values( + donation_options=donation_options, + donation_descriptions=donation_descriptions, + is_donation=is_donation, + **kwargs + ) + if is_donation: + if kwargs.get('donation_frequency') and kwargs.get('donation_frequency') == 'monthly': + is_monthly = True + else: + is_monthly = False + rendering_context.update({ + 'is_onetime': not is_monthly, + 'is_monthly': is_monthly, + }) + return rendering_context + + def _create_transaction(self, partner_id, *args, custom_create_values=None, **kwargs): + if kwargs.get('donation_frequency'): + if not custom_create_values: + custom_create_values = {} + if 'donation_frequency' not in custom_create_values: # We are in the payment module's flow + custom_create_values['donation_frequency'] = kwargs.pop('donation_frequency') + if kwargs.get('donation_partner_details'): + res_partner_obj = request.env['res.partner'].sudo() + details = kwargs.pop('donation_partner_details') + country_id = int(details.get('country_id')) + email = details.get('email') + partner_id = res_partner_obj.search( + [('email', '=ilike', email), ('country_id', '=', country_id)], + limit=1).id + if not partner_id: + partner_id = res_partner_obj.create({'name': details.get('name'), 'email': email, + 'country_id': country_id}).id + return super()._create_transaction(partner_id=partner_id, *args, custom_create_values=custom_create_values, + **kwargs) diff --git a/website_payment_recurring_donations/data/donation_data.xml b/website_payment_recurring_donations/data/donation_data.xml new file mode 100755 index 0000000..6b10dea --- /dev/null +++ b/website_payment_recurring_donations/data/donation_data.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/website_payment_recurring_donations/i18n/nl.po b/website_payment_recurring_donations/i18n/nl.po new file mode 100755 index 0000000..0c899f6 --- /dev/null +++ b/website_payment_recurring_donations/i18n/nl.po @@ -0,0 +1,86 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * website_payment_recurring_donations +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-09-22 13:35+0000\n" +"PO-Revision-Date: 2023-09-22 13:35+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.s_donation_button +msgid "Give Monthly" +msgstr "Geef maandelijks" + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.s_donation_button +msgid "Just Once" +msgstr "Slechts één keer" + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.donation_mail_body +msgid "As you have opted for recurring donations, fixed" +msgstr "Omdat u heeft gekozen voor terugkerende donaties, vast" + +#. module: website_payment_recurring_donations +#: model:ir.model.fields,field_description:website_payment_recurring_donations.field_payment_transaction__donation_frequency +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.payment_checkout +msgid "Donation Frequency" +msgstr "Donatie Frequentie" + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.payment_checkout +msgid "Give Monthly" +msgstr "Geef maandelijks" + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.payment_checkout +msgid "Just Once" +msgstr "Slechts één keer" + +#. module: website_payment_recurring_donations +#: model:ir.model.fields.selection,name:website_payment_recurring_donations.selection__payment_transaction__donation_frequency__monthly +msgid "Monthly" +msgstr "Maandelijks" + +#. module: website_payment_recurring_donations +#: model:ir.model.fields.selection,name:website_payment_recurring_donations.selection__payment_transaction__donation_frequency__onetime +msgid "One Time" +msgstr "Eenmaal" + +#. module: website_payment_recurring_donations +#: model:ir.model,name:website_payment_recurring_donations.model_payment_transaction +msgid "Payment Transaction" +msgstr "Betalingstransactie" + +#. module: website_payment_recurring_donations +#: model:ir.model.fields,field_description:website_payment_recurring_donations.field_payment_transaction__recurring_donation_provider_reference +msgid "Provider Reference For Recurring Donation" +msgstr "Providerreferentie voor terugkerende donaties" + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.donation_mail_body +msgid "" +"anniversary\n" +" of the first donation.You can submit your cancellation request by emailing to the address: (processing would be done within 3 business days)." +msgstr "" +"verjaardag\n" +" van de eerste donatie.Je kunt je annuleringsverzoek indienen door een e-mail te sturen naar het volgende adres: (verwerking zal binnen 3 werkdagen plaatsvinden)." + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.donation_mail_body +msgid "on the" +msgstr "op de" + +#. module: website_payment_recurring_donations +#: model_terms:ir.ui.view,arch_db:website_payment_recurring_donations.donation_mail_body +msgid "payments will be debited by" +msgstr "betalingen worden gedebiteerd door" diff --git a/website_payment_recurring_donations/models/__init__.py b/website_payment_recurring_donations/models/__init__.py new file mode 100755 index 0000000..ea7d6a3 --- /dev/null +++ b/website_payment_recurring_donations/models/__init__.py @@ -0,0 +1 @@ +from . import payment_transaction \ No newline at end of file diff --git a/website_payment_recurring_donations/models/payment_transaction.py b/website_payment_recurring_donations/models/payment_transaction.py new file mode 100755 index 0000000..e970a35 --- /dev/null +++ b/website_payment_recurring_donations/models/payment_transaction.py @@ -0,0 +1,29 @@ +# Copyright 2023 Onestein - Anjeel Haria +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PaymentTransaction(models.Model): + _inherit = 'payment.transaction' + + donation_frequency = fields.Selection( + [ + ('onetime', 'One Time'), + ('monthly', 'Monthly') + ], + string='Donation Frequency' + ) + recurring_donation_provider_reference = fields.Char('Provider Reference For Recurring Donation') + is_recurring_donation_terminated = fields.Boolean('Is Recurring Donation Terminated') + + def _send_donation_email(self, is_internal_notification=False, comment=None, recipient_email=None): + self = self.with_context(lang=self.partner_lang) + return super()._send_donation_email(is_internal_notification, comment, recipient_email) + + def action_terminate_recurring_donation(self): + # This method needs to be extended in each provider module. + # This method cancels/terminates the recurring donation on the provider end + return True + + diff --git a/website_payment_recurring_donations/static/src/js/website_payment_form.js b/website_payment_recurring_donations/static/src/js/website_payment_form.js new file mode 100755 index 0000000..6f6c20a --- /dev/null +++ b/website_payment_recurring_donations/static/src/js/website_payment_form.js @@ -0,0 +1,15 @@ +/** @odoo-module **/ +/* Copyright 2023 Onestein - Anjeel Haria + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +import checkoutForm from 'payment.checkout_form'; + +checkoutForm.include({ + _prepareTransactionRouteParams: function (code, paymentOptionId, flow) { + const transactionRouteParams = this._super(...arguments); + return $('.o_donation_payment_form').length ? { + ...transactionRouteParams, + 'donation_frequency':this.$('input[name="donation_frequency"]:checked').val(), + } : transactionRouteParams; + }, +}); diff --git a/website_payment_recurring_donations/static/src/snippets/s_donation/000.js b/website_payment_recurring_donations/static/src/snippets/s_donation/000.js new file mode 100755 index 0000000..806801d --- /dev/null +++ b/website_payment_recurring_donations/static/src/snippets/s_donation/000.js @@ -0,0 +1,18 @@ +/** @odoo-module **/ +/* Copyright 2023 Onestein - Anjeel Haria + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +import publicWidget from 'web.public.widget'; +const DonationSnippet = publicWidget.registry.DonationSnippet; +DonationSnippet.include({ + events: _.extend({}, DonationSnippet.prototype.events, { + 'click .donation_frequency': '_onClickDonationFrequency', + }), + + _onClickDonationFrequency(ev){ + const $button = $(ev.currentTarget); + this.$('.donation_frequency').parent('label').removeClass('active'); + $button.parent('label').addClass('active'); + }, + +}); diff --git a/website_payment_recurring_donations/static/src/snippets/s_donation/000.scss b/website_payment_recurring_donations/static/src/snippets/s_donation/000.scss new file mode 100755 index 0000000..933506b --- /dev/null +++ b/website_payment_recurring_donations/static/src/snippets/s_donation/000.scss @@ -0,0 +1,16 @@ +.s_donation:not([data-vcss]) { + .donation_frequency{ + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + border: 0; + clip: rect(0 0 0 0); + } +} + +.o_donation_payment_form{ + @include o-input-number-no-arrows(); +} diff --git a/website_payment_recurring_donations/views/donation_templates.xml b/website_payment_recurring_donations/views/donation_templates.xml new file mode 100755 index 0000000..2d73721 --- /dev/null +++ b/website_payment_recurring_donations/views/donation_templates.xml @@ -0,0 +1,33 @@ + + + + + + + diff --git a/website_payment_recurring_donations/views/payment_transaction_view.xml b/website_payment_recurring_donations/views/payment_transaction_view.xml new file mode 100755 index 0000000..70f0c05 --- /dev/null +++ b/website_payment_recurring_donations/views/payment_transaction_view.xml @@ -0,0 +1,37 @@ + + + + + + Recurring Donations Form + payment.transaction + + +
+ +
+ + + + +
+
+ + + Payment Transactions + payment.transaction + tree,form + [('partner_id','=', active_id)] + {'create': False} + +
\ No newline at end of file diff --git a/website_payment_recurring_donations/views/res_partner_view.xml b/website_payment_recurring_donations/views/res_partner_view.xml new file mode 100755 index 0000000..0757ed6 --- /dev/null +++ b/website_payment_recurring_donations/views/res_partner_view.xml @@ -0,0 +1,17 @@ + + + + + res.partner + + +