Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] Improved ordering process of applications #62

Merged
merged 3 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion argocd_capacity/views/application_tag_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<field name="model">argocd.application.tag</field>
<field name="inherit_id" ref="argocd_deployer.application_tag_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='domain_yaml_path']" position="after">
<xpath expr="//field[@name='key']" position="after">
<field name="volume_claim_count" attrs="{'invisible': [('is_odoo_module', '=', True)]}" />
</xpath>
</field>
Expand Down
2 changes: 1 addition & 1 deletion argocd_capacity/views/application_template_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<field name="model">argocd.application.template</field>
<field name="inherit_id" ref="argocd_deployer.application_template_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after">
<xpath expr="//field[@name='key']" position="after">
<field name="volume_claim_count" />
</xpath>
</field>
Expand Down
1 change: 1 addition & 0 deletions argocd_deployer/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"data/application_namespace_prefix.xml",
"data/application_set_template.xml",
"data/application_set.xml",
"views/application_domain_view.xml",
"views/application_template_view.xml",
"views/application_set_template_view.xml",
"views/application_tag_view.xml",
Expand Down
2 changes: 0 additions & 2 deletions argocd_deployer/data/application_set.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
<field name="branch">main</field>
<field name="repository_directory">/home/tarteo/repo</field>
<field name="deployment_directory">instances</field>
<field name="domain_format">%(application_name)s.curq.k8s.onestein.eu</field>
<field name="subdomain_format">%(subdomain)s.%(application_name)s.curq.k8s.onestein.eu</field>
<field name="template_id" ref="application_set_template_default"/>
<field name="namespace_prefix_id" ref="argocd_deployer.namespace_prefix_flavoured_odoo"/>
<field name="master_application_set_id" ref="argocd_deployer.application_set_master"/>
Expand Down
1 change: 0 additions & 1 deletion argocd_deployer/demo/application_tag_demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@
<field name="name">Matomo Server</field>
<field name="key">matomo_server</field>
<field name="is_odoo_module" eval="False" />
<field name="domain_yaml_path">matomo.domain</field>
</record>
</odoo>
2 changes: 1 addition & 1 deletion argocd_deployer/demo/application_template_demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<field name="name">Curq Basis</field>
<field name="config">
helm: |
domain: {{ get_value("domain", format_domain()) }}
domain: {{ create_domain(application.name + ".example.com", scope="Curq") }}
modules: website{{ application.modules and ',' + application.modules or '' }}
{%- if has_tag('matomo_server') %}
matomo:
Expand Down
2 changes: 1 addition & 1 deletion argocd_deployer/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
from . import application_template
from . import application
from . import application_tag
from . import application_tag_domain_override
from . import application_value
from . import application_namespace_prefix
from . import application_domain
80 changes: 36 additions & 44 deletions argocd_deployer/models/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import re

import jinja2
import yaml
from git import Repo
from yaml import Loader

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
Expand Down Expand Up @@ -42,6 +40,11 @@ class Application(models.Model):
inverse_name="application_id",
string="Values",
)
domain_ids = fields.One2many(
comodel_name="argocd.application.domain",
inverse_name="application_id",
string="Domains",
)
application_set_id = fields.Many2one(
"argocd.application.set",
)
Expand All @@ -61,23 +64,12 @@ def has_tag(self, key):
self.ensure_one()
return bool(self.tag_ids.filtered(lambda t: t.key == key))

def format_domain(self, subdomain=None):
"""
Helper method for generating the yaml / helm values. If no domain is specified in e.g. value_ids this can be used
to make a default domain.
Uses config parameters `argocd.application_subdomain_format` and `argocd.application_domain_format` for the format.

@param subdomain: tag key (e.g. matomo)
@return: formatted domain
"""
def create_domain(self, preferred, *alternatives, scope="global"):
"""Shortcut"""
self.ensure_one()
values = {"application_name": self.name}
if subdomain:
domain_format = self.application_set_id.subdomain_format or ""
values["subdomain"] = subdomain
else:
domain_format = self.application_set_id.domain_format or ""
return domain_format % values
return self.env["argocd.application.domain"].create_domain(
self, preferred, *alternatives, scope=scope
)

@api.depends("config")
def _compute_description(self):
Expand Down Expand Up @@ -132,28 +124,16 @@ def _render_description(self):
raise_if_not_found=False,
)

@staticmethod
def _get_domain(helm):
return helm.get("domain") or helm.get("global", {}).get("domain")

def get_urls(self):
self.ensure_one()
urls = []
if not self.config:
return urls

config = yaml.load(self.config, Loader=Loader)
helm = yaml.load(config["helm"], Loader=Loader)
urls.append(("https://%s" % self._get_domain(helm), "Odoo"))
for tag in self.tag_ids.filtered(lambda t: bool(t.domain_yaml_path)):
yaml_path = tag.get_domain_yaml_path(self.application_set_id).split(".")
domain = helm
for p in yaml_path:
domain = domain.get(p)
if not domain:
break
else:
urls.append(("https://%s" % domain, tag.name))
for scope in self.domain_ids.mapped("scope"):
prioritized_domain = self.domain_ids.filtered(
lambda d: d.scope == scope
).sorted("sequence")[0]
urls.append(
("https://%s" % prioritized_domain.name, prioritized_domain.scope)
)
return urls

@api.depends("tag_ids", "tag_ids.is_odoo_module")
Expand All @@ -163,20 +143,32 @@ def _compute_modules(self):
application.tag_ids.filtered(lambda t: t.is_odoo_module).mapped("key")
)

_sql_constraints = [("application_name_unique", "unique(name)", "Already exists")]
_sql_constraints = [
(
"application_name_unique",
"unique(application_set_id, name)",
"Already exists in this application set",
)
]

@api.model
def find_next_available_name(self, name):
def find_next_available_name(self, app_set, name):
"""
Find a name which is available based on name (e.g. greg2)

@param app_set: application set
@param name: a name
@return: first available name
"""
if not self.search([("name", "=", name)], count=True):
if not self.search(
[("application_set_id", "=", app_set.id), ("name", "=", name)], count=True
):
return name
i = 0
while self.search([("name", "=", name + str(i))], count=True):
while self.search(
[("application_set_id", "=", app_set.id), ("name", "=", name + str(i))],
count=True,
):
i += 1
return name + str(i)

Expand All @@ -197,7 +189,7 @@ def _get_config_render_values(self):
"application": self,
"has_tag": self.has_tag,
"get_value": self.get_value,
"format_domain": self.format_domain,
"create_domain": self.create_domain,
}

def render_config(self, context=None):
Expand Down Expand Up @@ -263,11 +255,11 @@ def immediate_destroy(self):
self.ensure_one()
self._apply_repository_changes(self._get_destroy_content)

def destroy(self):
def destroy(self, eta=0):
self.ensure_one()
delay = safe_eval(
self.env["ir.config_parameter"].get_param(
"argocd.application_destruction_delay", "0"
)
)
self.with_delay(eta=delay).immediate_destroy()
self.with_delay(eta=eta or delay).immediate_destroy()
46 changes: 46 additions & 0 deletions argocd_deployer/models/application_domain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from odoo import api, fields, models


class ApplicationDomain(models.Model):
_name = "argocd.application.domain"
_description = "ArgoCD Application Domain"
_order = "sequence"

application_id = fields.Many2one(comodel_name="argocd.application", required=True)
scope = fields.Char(default="Application")
sequence = fields.Integer(default=10)
name = fields.Char(required=True)

_sql_constraints = [
(
"application_domain_name_unique",
"unique(name)",
"Domain is already in use",
)
]

@api.model
def create_domain(self, application, preferred, *alternatives, scope="Application"):
existing = application.domain_ids.filtered(lambda d: d.scope == scope).sorted(
"sequence"
)
if existing:
return existing.name
domains = (preferred,) + alternatives
i = 0
best_available = False
while not best_available:
i_as_str = str(i)
for domain in domains:
domain_name = domain
if i:
domain_name += i_as_str
already_exists = self.search([("name", "=", domain_name)], count=True)
if not already_exists:
best_available = domain_name
break
i += 1
self.create(
{"application_id": application.id, "name": best_available, "scope": scope}
)
return best_available
10 changes: 0 additions & 10 deletions argocd_deployer/models/application_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ class ApplicationSet(models.Model):
deployment_directory = fields.Char(
help="Folder inside the repository in which to store the application YAML files.",
)
domain_format = fields.Char(
required=True,
help="The domain format used to build the domain for the deployment.",
default="-",
)
subdomain_format = fields.Char(
required=True,
help="The domain format used to build the domain for the deployment.",
default="-",
)
namespace_prefix_id = fields.Many2one("argocd.application.namespace.prefix")

_sql_constraints = [
Expand Down
20 changes: 0 additions & 20 deletions argocd_deployer/models/application_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,5 @@ class ApplicationTag(models.Model):
name = fields.Char(required=True)
key = fields.Char(required=True, copy=False)
is_odoo_module = fields.Boolean(string="Is additional Odoo Module")
domain_yaml_path = fields.Char(
help="Path where to find the domain in the yaml (e.g. nextcloud.domain)"
)
domain_override_ids = fields.One2many(
"argocd.application.tag.domain.override", inverse_name="tag_id"
)

_sql_constraints = [("application_tag_key_unique", "unique(key)", "Already exists")]

def get_domain_yaml_path(self, application_set=False):
self.ensure_one()
if (
not application_set
or application_set.id not in self.domain_override_ids.application_set_id.ids
):
return self.domain_yaml_path or ""
return (
self.domain_override_ids.filtered(
lambda do: do.application_set_id == application_set
).domain_yaml_path
or ""
)
20 changes: 0 additions & 20 deletions argocd_deployer/models/application_tag_domain_override.py

This file was deleted.

7 changes: 1 addition & 6 deletions argocd_deployer/models/application_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,5 @@ class ApplicationTemplate(models.Model):
_description = "ArgoCD Application Template"

name = fields.Char(required=True)
config = fields.Text(
default="""helm: |
domain: dev.curq.k8s.onestein.eu
modules: website{{ application.modules and ',' + application.modules or '' }}
"""
)
config = fields.Text()
active = fields.Boolean(default=True)
2 changes: 1 addition & 1 deletion argocd_deployer/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ application_tag_access,application_tag_access,model_argocd_application_tag,base.
application_value_access,application_value_access,model_argocd_application_value,base.group_system,1,1,1,1
application_set_access,application_set_access,model_argocd_application_set,base.group_system,1,1,1,1
application_set_template_access,application_set_template_access,model_argocd_application_set_template,base.group_system,1,1,1,1
application_tag_domain_override_access,application_tag_domain_override_access,model_argocd_application_tag_domain_override,base.group_system,1,1,1,1
application_namespace_prefix_access,application_namespace_prefix_access,model_argocd_application_namespace_prefix,base.group_system,1,1,1,1
application_domain_access,application_domain_access,model_argocd_application_domain,base.group_system,1,1,1,1
58 changes: 0 additions & 58 deletions argocd_deployer/tests/test_application_tag.py

This file was deleted.

Loading
Loading