update
This commit is contained in:
parent
7384400cd4
commit
9d2c456c59
45 changed files with 219 additions and 327 deletions
182
doc/link.md
182
doc/link.md
|
@ -1,177 +1,13 @@
|
||||||
# Configuration liée
|
CAS 1 (Redis et RedisClient) :
|
||||||
|
|
||||||
Une configuration liée est un ensemble d'élément partagé entre deux serveurs différents.
|
application service "serveur" :
|
||||||
|
|
||||||
## Lier un client à un serveur
|
provider="xxx" : variable multiple qui récupère tous les noms de domaine des suppliers
|
||||||
|
provider="xxx:yyy" : variable dans une famille dynamique qui récupère les infos de yyy
|
||||||
|
supplier="xxx:zzz" : variable dans la famille dynamique qui transmet l'info de zzz (généralement par un calcul)
|
||||||
|
|
||||||
```
|
application service "client" :
|
||||||
<check name="set_linked">
|
|
||||||
<param name="linked_provider">clients</param>
|
|
||||||
<param name="linked_value" type="variable">service_variable</param>
|
|
||||||
<target>service_variable_2</target>
|
|
||||||
</check>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Lier un client à un serveur avec un nom d'utilisateur issu du nom de domaine
|
supplier="xxx" : variable qui récupère le nom de domaine du provider
|
||||||
|
supplier="xxx:yyy" : variable qui transmet les infos de yyy (généralement par un calcul)
|
||||||
Il faut commencer de créer une variable côté serveur :
|
provider="xxx:zzz" : variable récupère les infos de zzz
|
||||||
|
|
||||||
```
|
|
||||||
<variable name="remotes" description="All clients" type="domainname" multi="True" provider="clients"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
Le nom d'utilisateur sera ici le nom de domaine du serveur avec l'application de la fonction 'normalize_family'.
|
|
||||||
|
|
||||||
Pour lier deux configurations il faut créer deux variables côté client :
|
|
||||||
|
|
||||||
```
|
|
||||||
<variable name='service_server_address' type='domainname' description="Nom DNS du serveur" mandatory='True'/>
|
|
||||||
<variable name='service_remote_user' type='string' description="Remote username" mandatory='True' hidden="True"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
Enfin il faut lier les deux configurations :
|
|
||||||
|
|
||||||
```
|
|
||||||
<fill name="set_linked">
|
|
||||||
<param name="linked_server" type="variable">service_server_address</param>
|
|
||||||
<param name="linked_provider">clients</param>
|
|
||||||
<param name="linked_value" type="information">server_name</param>
|
|
||||||
<target>service_remote_user</target>
|
|
||||||
</fill>
|
|
||||||
```
|
|
||||||
|
|
||||||
Ainsi, lorsque l'utilisateur renseignera la variable "service_server_address", cette valeur sera ajouter à la variable "remotes" du serveur.
|
|
||||||
En retour la variable "service_remote_user" aura comme valeur "normalize_family(service_server_address)".
|
|
||||||
|
|
||||||
## Lier un client unique à un serveur avec un nom d'utilisateur calculé sur le serveur
|
|
||||||
|
|
||||||
Il faut commencer de créer les variables côté serveur :
|
|
||||||
|
|
||||||
```
|
|
||||||
<variables>
|
|
||||||
<variable name="remote" description="The client" type="domainname" provider="client"/>
|
|
||||||
<variable name="username" hidden="True" provider="client_name"/>
|
|
||||||
</variables>
|
|
||||||
<constraints>
|
|
||||||
<fill name="gen_user_name">
|
|
||||||
<target>username</target>
|
|
||||||
</fill>
|
|
||||||
</constraints>
|
|
||||||
```
|
|
||||||
|
|
||||||
Côté client :
|
|
||||||
|
|
||||||
```
|
|
||||||
<variable name='service_server_address' type='domainname' description="Nom DNS du serveur" mandatory='True'/>
|
|
||||||
<variable name='service_remote_user' type='string' description="Remote username" mandatory='True' hidden="True"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
<fill name="set_linked">
|
|
||||||
<param name="linked_server" type="variable">service_server_address</param>
|
|
||||||
<param name="linked_provider">clients</param>
|
|
||||||
<param name="linked_value" type="information">server_name</param>
|
|
||||||
<param name="linked_returns">client_name</param>
|
|
||||||
<target>service_remote_user</target>
|
|
||||||
</fill>
|
|
||||||
```
|
|
||||||
|
|
||||||
Ainsi, lorsque l'utilisateur renseignera la variable "service_server_address", cette valeur sera la variable "remote" du serveur.
|
|
||||||
Un nom d'utilisateur sera alors généré côté serveur, la valeur de ce nom sera retourner au client comme valeur de 'service_remote_user'.
|
|
||||||
|
|
||||||
## Lier plusieurs clients à un serveur avec un nom d'utilisateur calculé sur le serveur
|
|
||||||
|
|
||||||
Il faut commencer de créer les variables côté serveur :
|
|
||||||
|
|
||||||
```
|
|
||||||
<variables>
|
|
||||||
<variable name="remotes" description="All clients" type="domainname" multi="True" provider="clients"/>
|
|
||||||
<family name="remote_" description="Compte pour " dynamic="remotes">
|
|
||||||
<variable name="username_" hidden="True" provider="client_name"/>
|
|
||||||
</family>
|
|
||||||
</variables>
|
|
||||||
<constraints>
|
|
||||||
<fill name="gen_user_name">
|
|
||||||
<target>username_</target>
|
|
||||||
</fill>
|
|
||||||
</constraints>
|
|
||||||
```
|
|
||||||
|
|
||||||
Côté client :
|
|
||||||
|
|
||||||
```
|
|
||||||
<variable name='service_server_address' type='domainname' description="Nom DNS du serveur" mandatory='True'/>
|
|
||||||
<variable name='service_remote_user' type='string' description="Remote username" mandatory='True' hidden="True"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
<fill name="set_linked">
|
|
||||||
<param name="linked_server" type="variable">service_server_address</param>
|
|
||||||
<param name="linked_provider">clients</param>
|
|
||||||
<param name="linked_value" type="information">server_name</param>
|
|
||||||
<param name="linked_returns">client_name</param>
|
|
||||||
<param name="dynamic" type="information">server_name</param>
|
|
||||||
<target>service_remote_user</target>
|
|
||||||
</fill>
|
|
||||||
```
|
|
||||||
|
|
||||||
Ainsi, lorsque l'utilisateur renseignera la variable "service_server_address", cette valeur sera ajouter à la variable "remotes" du serveur.
|
|
||||||
Un nom d'utilisateur sera alors généré côté serveur, la valeur de ce nom sera retourner au client comme valeur de 'service_remote_user'.
|
|
||||||
|
|
||||||
## Caculer une variable d'un client par rapport à la valeur d'un serveur
|
|
||||||
|
|
||||||
Il faut commencer de créer une nouvelle variables côté serveur par exemple dans une famille dynamique :
|
|
||||||
|
|
||||||
```
|
|
||||||
<variables>
|
|
||||||
<family name="remote_" description="Compte pour " dynamic="remotes">
|
|
||||||
<variable name="password_" description="Password " auto_save="True" hidden="True" type="password" provider="client_password"/>
|
|
||||||
</family>
|
|
||||||
</variables>
|
|
||||||
<constraints>
|
|
||||||
<fill name="gen_password">
|
|
||||||
<target>password_</target>
|
|
||||||
</fill>
|
|
||||||
</constraints>
|
|
||||||
```
|
|
||||||
|
|
||||||
Côté client on veut récupérer ce mot de passe dans une variable :
|
|
||||||
|
|
||||||
```
|
|
||||||
<variable name='service_remote_user_password' type='password' description="Remote password" mandatory='True' hidden="True"/>
|
|
||||||
```
|
|
||||||
|
|
||||||
Et calculer cette valeur :
|
|
||||||
|
|
||||||
```
|
|
||||||
<fill name="get_linked_configuration">
|
|
||||||
<param name="linked_server" type="variable">service_server_address</param>
|
|
||||||
<param name="linked_provider">client_password</param>
|
|
||||||
<param name="dynamic" type="variable">service_remote_user</param>
|
|
||||||
<target>service_remote_user_password</target>
|
|
||||||
</fill>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Propoger la valeur d'une variable d'un client vers un serveur
|
|
||||||
|
|
||||||
```
|
|
||||||
<check name="set_linked_configuration">
|
|
||||||
<param name="linked_server" type="variable">service_server_address</param>
|
|
||||||
<param name="linked_provider">client_var</param>
|
|
||||||
<param name="dynamic" type="variable">service_remote_user</param>
|
|
||||||
<target>service_variable</target>
|
|
||||||
</check>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Propoger la valeur d'une variable d'un client vers un variable esclave du serveur
|
|
||||||
|
|
||||||
```
|
|
||||||
<check name="set_linked_configuration">
|
|
||||||
<param name="linked_server" type="variable">service_server_address</param>
|
|
||||||
<param name="leader_provider">client_var</param>
|
|
||||||
<param name="leader_value" type="variable">service_variable</param>
|
|
||||||
<param name="linked_provider">slave</param>
|
|
||||||
<param name="dynamic" type="variable">service_server_address</param>
|
|
||||||
<target>service_variable_2</target>
|
|
||||||
</check>
|
|
||||||
```
|
|
||||||
|
|
|
@ -86,4 +86,5 @@ def get_zone_name(zones: list,
|
||||||
|
|
||||||
|
|
||||||
def get_last_server_name(server_names):
|
def get_last_server_name(server_names):
|
||||||
|
if server_names:
|
||||||
return server_names[-1]
|
return server_names[-1]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<rougail version="0.10">
|
<rougail version="0.10">
|
||||||
<variables>
|
<variables>
|
||||||
<variable name="providers" hidden="True"/>
|
<!--variable name="providers" hidden="True"/-->
|
||||||
<variable name="copy_tests" type="boolean" mandatory="True" hidden="True"/>
|
<variable name="copy_tests" type="boolean" mandatory="True" hidden="True"/>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
<constraints>
|
||||||
|
|
|
@ -21,6 +21,9 @@ def get_ip(zones: dict,
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise ValueError(f'cannot find IP in domain name "{domain_name}" (for "{s_name}")')
|
raise ValueError(f'cannot find IP in domain name "{domain_name}" (for "{s_name}")')
|
||||||
|
if host_name == zone['host_name']:
|
||||||
|
ret = zone['host_ip']
|
||||||
|
else:
|
||||||
if not host_name in zone['hosts']:
|
if not host_name in zone['hosts']:
|
||||||
continue
|
continue
|
||||||
ret = zone['hosts'][host_name]
|
ret = zone['hosts'][host_name]
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<variable name="dns_is_only_local" type="boolean" description="DNS resolve only local address" hidden="True">
|
<variable name="dns_is_only_local" type="boolean" description="DNS resolve only local address" hidden="True">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable name="dns_client_address" type="domainname" description="Nom de domaine du serveur DNS" supplier="LocalDNS" hidden="True" mandatory="True"/>
|
<variable name="dns_client_address" type="domainname" supplier="LocalDNS" hidden="True" mandatory="True"/>
|
||||||
<variable name="ip_dns" type="ip" description="Adresse IP du serveur DNS" hidden="True"/>
|
<variable name="ip_dns" type="ip" description="Adresse IP du serveur DNS" hidden="True"/>
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
|
|
|
@ -3,13 +3,13 @@ addresses:
|
||||||
{% if 'dns_client_address' in general.network %}
|
{% if 'dns_client_address' in general.network %}
|
||||||
- dns_address: '{{ general.network.dns_client_address }}'
|
- dns_address: '{{ general.network.dns_client_address }}'
|
||||||
dns_ip: '{{ ip_dns }}'
|
dns_ip: '{{ ip_dns }}'
|
||||||
{% elif 'unbound_forward_address' in general.dns_resolver.forward_zones %}
|
{% elif 'dns_resolver' in general and 'unbound_forward_address' in general.dns_resolver.forward_zones.unbound_forward_address %}
|
||||||
{% for authority in general.dns_resolver.forward_zones.unbound_forward_address %}
|
{% for authority in general.dns_resolver.forward_zones.unbound_forward_address %}
|
||||||
- dns_address: {{ authority }}
|
- dns_address: {{ authority }}
|
||||||
dns_ip: {{ authority.unbound_allowed_client }}
|
dns_ip: {{ authority.unbound_allowed_client }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% elif 'nsd_zones' in general.dns_zone %}
|
{% elif 'dns_zone' in general and 'nsd_zones' in general.dns_zone %}
|
||||||
{%for zone in general.dns_zone.nsd_zones %}
|
{% for zone in general.dns_zone.nsd_zones %}
|
||||||
{% set suffix = zone|normalize_family %}
|
{% set suffix = zone|normalize_family %}
|
||||||
{% set hostnames = nsd["nsd_zone_" + suffix]["hostname_" + suffix]["hostname_" + suffix] %}
|
{% set hostnames = nsd["nsd_zone_" + suffix]["hostname_" + suffix]["hostname_" + suffix] %}
|
||||||
{% for hostname in hostnames %}
|
{% for hostname in hostnames %}
|
||||||
|
@ -18,7 +18,6 @@ addresses:
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% if dns_is_only_local %}
|
{% if dns_is_only_local %}
|
||||||
dns_is_only_local: true
|
dns_is_only_local: true
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<family name="dovecot" description="IMAP mail server">
|
<family name="dovecot" description="IMAP mail server">
|
||||||
<variable name="imap_internal_address" type="domainname" description="Adresse interne du serveur IMAP" mandatory="True" provider="IMAP"/>
|
<variable name="imap_internal_addresses" type="domainname" description="IMAP client address" mandatory="True" provider="IMAP" multi="True"/>
|
||||||
<variable name="well_known_filenames" type="filename" hidden='True' multi="True"/>
|
<variable name="well_known_filenames" type="filename" hidden='True' multi="True"/>
|
||||||
</family>
|
</family>
|
||||||
<family name="revprox">
|
<family name="revprox">
|
||||||
|
@ -93,10 +93,10 @@
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
<constraints>
|
||||||
<fill name="calc_value">
|
<!--fill name="calc_value">
|
||||||
<param type="variable">domain_name_eth0</param>
|
<param type="variable">domain_name_eth0</param>
|
||||||
<target>imap_internal_address</target>
|
<target>imap_internal_address</target>
|
||||||
</fill>
|
</fill-->
|
||||||
<fill name="calc_value">
|
<fill name="calc_value">
|
||||||
<param type="variable">mail_domains</param>
|
<param type="variable">mail_domains</param>
|
||||||
<target>mail_domains_calc</target>
|
<target>mail_domains_calc</target>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{%set username="rougail_test@silique.fr" %}
|
{% set username="rougail_test@silique.fr" %}
|
||||||
{%set username_family="rougail_test@gnunux.info" %}
|
{% set username_family="rougail_test@gnunux.info" %}
|
||||||
{%set name_family="gnunux" %}
|
{% set name_family="gnunux" %}
|
||||||
address: {{ general.network.interface_0.ip_eth0 }}
|
address: {{ general.network.interface_0.ip_eth0 }}
|
||||||
dns: {{ general.network.interface_0.domain_name_eth0 }}
|
dns: {{ general.network.interface_0.domain_name_eth0 }}
|
||||||
username: {{ username }}
|
username: {{ username }}
|
||||||
password: {{ username|get_password(server_name='test', description="test", type="cleartext", hide=hide_secret, temporary=True) }}
|
password: {{ username|get_password(server_name='test', description="test", type="cleartext", hide=hide_secret, temporary=True) }}
|
||||||
username_family: {{ username_family }}
|
username_family: {{ username_family }}
|
||||||
password_family: {{ username_family|get_password(server_name='test', description='test', type="cleartext", hide=hide_secret, temporary=True)
|
password_family: {{ username_family|get_password(server_name='test', description='test', type="cleartext", hide=hide_secret, temporary=True) }}
|
||||||
name_family: {{ name_family }}
|
name_family: {{ name_family }}
|
||||||
smtp: {{ general.smtp.smtp_relay_ip }}
|
smtp: {{ general.smtp.smtp_relay_ip }}
|
||||||
ext_username: 'test@example.net'
|
ext_username: 'test@example.net'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% set username="rougail_test@silique.fr" %}
|
{% set username="rougail_test@silique.fr" %}
|
||||||
ip: {{ general.network.interface_0.ip_eth0 }}
|
ip: {{ general.network.interface_0.ip_eth0 }}
|
||||||
revprox_ip: {{ general.revprox.revprox_client.revprox_client_server_ip }}
|
revprox_ip: {{ general.revprox.revprox_client_server_ip }}
|
||||||
{% set domain = {{ general.revprox.revprox_client.revprox_client_external_domainnames[0] }}
|
{% set domain = {{ general.revprox.revprox_client_external_domainnames[0] }}
|
||||||
base_url: https://{{ domain }}{{domain.revprox_client_location }}
|
base_url: https://{{ domain }}{{domain.revprox_client_location }}
|
||||||
auth_url: {{ general.oauth2_client.oauth2_client_external[0] }}
|
auth_url: {{ general.oauth2_client.oauth2_client_external[0] }}
|
||||||
auth_server: {{ general.oauth2_client.oauth2_server_domainname }}
|
auth_server: {{ general.oauth2_client.oauth2_server_domainname }}
|
||||||
|
|
|
@ -21,15 +21,13 @@
|
||||||
<file engine="none">/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-37-x86_64</file>
|
<file engine="none">/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-37-x86_64</file>
|
||||||
<file engine="none">/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-38-x86_64</file>
|
<file engine="none">/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-38-x86_64</file>
|
||||||
<file engine="none">/etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-36</file>
|
<file engine="none">/etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-36</file>
|
||||||
|
<file engine="none">/etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-38</file>
|
||||||
<file engine="ansible">/etc/sysctl.d/90-risotto.conf</file>
|
<file engine="ansible">/etc/sysctl.d/90-risotto.conf</file>
|
||||||
<file engine="ansible" file_type="variable" source="dhcp.network" variable="interface_names">host_network_filename</file>
|
<file engine="ansible" file_type="variable" source="dhcp.network" variable="interface_names">host_network_filename</file>
|
||||||
</service>
|
</service>
|
||||||
<service name="modprobe@">
|
<service name="modprobe@">
|
||||||
<override/>
|
<override/>
|
||||||
</service>
|
</service>
|
||||||
<service name="resolvconf-pull-resolved">
|
|
||||||
<override/>
|
|
||||||
</service>
|
|
||||||
<service name="vector" servicelist="vector">
|
<service name="vector" servicelist="vector">
|
||||||
<file engine="ansible">/etc/vector/vector.toml</file>
|
<file engine="ansible">/etc/vector/vector.toml</file>
|
||||||
</service>
|
</service>
|
||||||
|
@ -70,6 +68,10 @@
|
||||||
<value>python3-psycopg2</value>
|
<value>python3-psycopg2</value>
|
||||||
<value>python3-redis</value>
|
<value>python3-redis</value>
|
||||||
<value>python3-imaplib2</value>
|
<value>python3-imaplib2</value>
|
||||||
|
<value>python3-pymysql</value>
|
||||||
|
</variable>
|
||||||
|
<variable name="host_removed_packages" multi="True" hidden="True">
|
||||||
|
<value>resolvconf</value>
|
||||||
</variable>
|
</variable>
|
||||||
<family name="network">
|
<family name="network">
|
||||||
<variable name="output_interface" description="Nom de l'interface de sortie" mandatory="True"/>
|
<variable name="output_interface" description="Nom de l'interface de sortie" mandatory="True"/>
|
||||||
|
@ -93,11 +95,11 @@
|
||||||
</family>
|
</family>
|
||||||
<family name="vector">
|
<family name="vector">
|
||||||
<variable name="server_address" type="domainname" hidden="True" supplier="Vector"/>
|
<variable name="server_address" type="domainname" hidden="True" supplier="Vector"/>
|
||||||
<variable name="ip_address" type="ip" hidden="True"/>
|
<variable name="ip_address" type="ip" hidden="True" supplier="Vector:address"/>
|
||||||
</family>
|
</family>
|
||||||
<family name="prometheus">
|
<family name="prometheus">
|
||||||
<variable name="prometheus_server_address" type="domainname" hidden="True" supplier="Prometheus"/>
|
<variable name="prometheus_server_address" type="domainname" hidden="True" supplier="Prometheus"/>
|
||||||
<variable name="prometheus_ip_address" type="ip" hidden="True" supplier="Prometheus:address"/>
|
<variable name="prometheus_ip_address" type="ip" hidden="True"/>
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
<constraints>
|
||||||
|
@ -144,7 +146,7 @@
|
||||||
<param type="variable">server_address</param>
|
<param type="variable">server_address</param>
|
||||||
<target>ip_address</target>
|
<target>ip_address</target>
|
||||||
</fill>
|
</fill>
|
||||||
<fill name="get_host_ip">
|
<fill name="get_ip">
|
||||||
<param type="information">zones</param>
|
<param type="information">zones</param>
|
||||||
<param type="variable">prometheus_server_address</param>
|
<param type="variable">prometheus_server_address</param>
|
||||||
<target>prometheus_ip_address</target>
|
<target>prometheus_ip_address</target>
|
||||||
|
@ -165,9 +167,5 @@
|
||||||
<target type="servicelist">vector</target>
|
<target type="servicelist">vector</target>
|
||||||
<target type="variable">ip_address</target>
|
<target type="variable">ip_address</target>
|
||||||
</condition>
|
</condition>
|
||||||
<condition name="disabled_if_in" source="prometheus_server_address">
|
|
||||||
<param type="nil"/>
|
|
||||||
<target type="variable">prometheus_ip_address</target>
|
|
||||||
</condition>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQINBF2tu8EBEADnI6bmlE7ebLuYSBKJavk7gwX8L2S0lDwtmAFmNcxQ/tAhh5Gx
|
||||||
|
2RKEneou12pSxav8MvbKOr4IpJLLmuoQMLYkbQRHovgVfDYdtvK9T8tZH51ACtnC
|
||||||
|
KKr9SucnKhWpDk3/n/djV0I2qSesE6QcJVrh66bT/8nbyIFbbiYLOgE88YAX5Wdj
|
||||||
|
TkgmYXJ54l1MP/3N64pFlmk6myYCrLh7cibFYLZOW2Xwfq6Go6HOpGn9Cazb+T6m
|
||||||
|
LALkVPERu2QkcUhMqy/slD5tFFb7DW1gkwnYiu5PKwThW7laZgmw2yAgDV+JccdK
|
||||||
|
D9ZHALmy9GyQ1ZjDptpa5BObE5vazbuAbSndoIqwaMxCrlqhIYdmqz4m/HJ9BaC0
|
||||||
|
mRSkT6N9SqytZXFhu5/Ld6+/Ol3b+q28bnV64qQrDH6hgnrRdqCQpm8g7tZFuk5X
|
||||||
|
JsB/A+EfI2kE6YXqWaGdEx0XcqOv97n6sRZNweOHX3vSM0eLwmM2dpgc7RvMfcqr
|
||||||
|
73ylZ9CnWVUD6cl+wE8SnGnVVqYau2spZFzKVAcfi/Zwvh6wM7/83XC2mkIHmoFR
|
||||||
|
OY5aDWFhoFZFgiHHnmDv6kACNmSHb/oYRkvwQ+JhAQu4I9CYw1sxaUDjwtt7a+4I
|
||||||
|
mBZM8WuvAVLkqnF+MJetiL15/W834HjCNITV03t9593T6Z1Dxpfv4hy7YwARAQAB
|
||||||
|
tFVSUE0gRnVzaW9uIGZyZWUgcmVwb3NpdG9yeSBmb3IgRmVkb3JhICgyMDIwKSA8
|
||||||
|
cnBtZnVzaW9uLWJ1aWxkc3lzQGxpc3RzLnJwbWZ1c2lvbi5vcmc+iQJFBBMBCAAv
|
||||||
|
FiEE6aSRo94keBTn4Gfq4G+OzdZR/y4FAl2tu8ECGwMECwkIBwMVCAoCHgECF4AA
|
||||||
|
CgkQ4G+OzdZR/y4ZQhAAmF5A4XC9ymd94BFwsbbpCnx2YlfmsZwT1QzBu9njjkH7
|
||||||
|
MC4THknYe2B/muE5dPu3NseZMzue1Ou4KbMz4wq82731prLRu+iHAxAxJ1qd8whA
|
||||||
|
QGuRJAg8+YEXKhpwpD/8P/xJo9IRmPxPM+6mQVTlASv34CEIGff1vJr40tNiU53P
|
||||||
|
PZq9SWD3/uG84PQRmGXetfF2K3NkXqzkvQSM68JZiYR2+wMkoO9f72B7LTBrfkwy
|
||||||
|
RcFPA7kj65pysB+l2wez03Dh/MyA3LTusd9M6FGiSOUVpQZ+NUFipIisS3vh/Bgp
|
||||||
|
zMsj1NSsMLjUDcX8stR8GfVgTxSgWwHTNl75XwTZpJOKMoj97kh9zzLwBhZ1W+xo
|
||||||
|
8s2W7YqVnOUl8rPm7ZbOefGkamNg8bhqcyNIEbHqR5QZVzDBT2AxVcB6jsxSHf5b
|
||||||
|
sb+KEJff4g6E4fWPA/IYdtJ7DItbVXnkAjqD7ADUh7Xq7pOgfC/4Cledf27x73m+
|
||||||
|
sdBvKsEBrroAsX/v4z46mQApszkfjTUAXwj2lUT+ujoktJHXqR71jbY0+8JX6Fyw
|
||||||
|
6ZW0emxR++bt9ksLcsNmjOQP9TmQpi2CW4Z+Ol2tlwtlnKAo6ecx4aacHKg+FYuQ
|
||||||
|
HTJRq6E6GpCPn1avf1v797RM+3zzw9TYkadfVLIQQ4HYbYzienOgGGporclrtrQ=
|
||||||
|
=oOVZ
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
|
@ -1,2 +0,0 @@
|
||||||
[Unit]
|
|
||||||
StartLimitIntervalSec=0
|
|
|
@ -24,7 +24,6 @@
|
||||||
</services>
|
</services>
|
||||||
<variables>
|
<variables>
|
||||||
<family name="nginx">
|
<family name="nginx">
|
||||||
<variable name="oauth2_client_external_domain" type="domainname" hidden="True" supplier="OAuth2Client:external_domain"/>
|
|
||||||
<variable name="nginx_default_https" redefine="True">
|
<variable name="nginx_default_https" redefine="True">
|
||||||
<value>False</value>
|
<value>False</value>
|
||||||
</variable>
|
</variable>
|
||||||
|
@ -43,10 +42,4 @@
|
||||||
</family>
|
</family>
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
|
||||||
<fill name="get_first_value">
|
|
||||||
<param type="variable">revprox_client_external_domainnames</param>
|
|
||||||
<target>oauth2_client_external_domain</target>
|
|
||||||
</fill>
|
|
||||||
</constraints>
|
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -18,13 +18,13 @@
|
||||||
<choice>HS512</choice>
|
<choice>HS512</choice>
|
||||||
<choice>RS256</choice>
|
<choice>RS256</choice>
|
||||||
</variable>
|
</variable>
|
||||||
|
<variable name="oauth2_client_external_domain_" type="domainname" hidden="True" supplier="OAuth2:external_domain"/>
|
||||||
</family>
|
</family>
|
||||||
<variable name="clients" description="Remote clients" type="domainname" multi="True" supplier="OAuth2Client"/>
|
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
<constraints>
|
||||||
<fill name="calc_value">
|
<fill name="get_first_value">
|
||||||
<param type="variable">oauth2.remotes</param>
|
<param type="variable">revprox_client_external_domainnames</param>
|
||||||
<target>oauth2.clients</target>
|
<target>oauth2.oauth2_.oauth2_client_external_domain_</target>
|
||||||
</fill>
|
</fill>
|
||||||
</constraints>
|
</constraints>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
address: {{ revprox_client_external_domainnames[0] }}
|
address: {{ revprox_client_external_domainnames[0] }}
|
||||||
internal_address: {{ domain_name_eth0 }}
|
internal_address: {{ domain_name_eth0 }}
|
||||||
ip: {{ ip_eth0 }}
|
ip: {{ general.network.interface_0.ip_eth0 }}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{% set username="rougail_test@silique.fr" %}
|
{% set username="rougail_test@silique.fr" %}
|
||||||
ip: {{ general.network.interface_0.ip_eth0 }}
|
ip: {{ general.network.interface_0.ip_eth0 }}
|
||||||
revprox_ip: {{ general.revprox.revprox_client.revprox_client_server_ip }}
|
revprox_ip: {{ general.revprox.revprox_client_server_ip }}
|
||||||
{% set domain = {{ general.revprox.revprox_client.revprox_client_external_domainnames[0] }}
|
{% set domain = general.revprox.revprox_client.revprox_client_external_domainnames[0] %}
|
||||||
domain_name: {{ domain }}
|
domain_name: {{ domain }}
|
||||||
base_url: https://{{ domain }}{{ domain.revprox_client_location }}
|
base_url: https://{{ domain }}{{ domain.revprox_client_location }}
|
||||||
auth_url: {{ general.oauth2_client.oauth2_client_external[0] }}
|
auth_url: {{ general.oauth2_client.external.oauth2_client_external[0] }}
|
||||||
auth_server: {{ general.oauth2_client.oauth2_server_domainname }}
|
auth_server: {{ general.oauth2_client.oauth2_server_domainname }}
|
||||||
username: {{ username }}
|
username: {{ username }}
|
||||||
password: username|get_password(server_name='test', description='test', type="cleartext", hide=hide_secret, temporary=True)
|
password: {{ username|get_password(server_name='test', description='test', type="cleartext", hide=hide_secret, temporary=True) }}
|
||||||
mailman_domain: {{ general.mailman.mailman_domains[0] }}
|
mailman_domain: {{ general.mailman.mailman_domains[0] }}
|
||||||
internal_address: {{ general.network.interface_0.domain_name_eth0 }}
|
internal_address: {{ general.network.interface_0.domain_name_eth0 }}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from yaml import load, SafeLoader
|
from yaml import load, SafeLoader
|
||||||
from os import environ
|
from os import environ
|
||||||
from os.path import join, isdir
|
from os.path import join, isdir
|
||||||
from revprox import Authentication
|
from revprox_client import Authentication
|
||||||
from execute import run
|
from execute import run
|
||||||
from re import search
|
from re import search
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
address: {{ general.network.interface_0.ip_eth0 }}
|
address: {{ general.network.interface_0.ip_eth0 }}
|
||||||
user: rougail_test
|
user: rougail_test
|
||||||
password: {{ 'rougail_test'|get_password(server_name=domain_name_eth0, description="remote", type="cleartext", hide={{ hide_secret }}, temporary=True) }}
|
password: {{ 'rougail_test'|get_password(server_name=domain_name_eth0, description="remote", type="cleartext", hide=hide_secret, temporary=True) }}
|
||||||
dbname: rougail_test
|
dbname: rougail_test
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
address: {{ ip_eth0 }}
|
address: {{ general.network.interface_0.ip_eth0 }}
|
||||||
nginx_default_http:
|
nginx_default_http:
|
||||||
{%- if 'nginx_default_http' in general.nginx and general.nginx.nginx_default_http and not 'revprox_client_external_domainnames' in general.revprox.revprox_client -%}
|
{%- if 'nginx_default_http' in general.nginx and general.nginx.nginx_default_http and not 'revprox_client_external_domainnames' in general.revprox.revprox_client -%}
|
||||||
true
|
true
|
||||||
{% else %}
|
{% else %}
|
||||||
false
|
false
|
||||||
{% endif %}
|
{% endif %}
|
||||||
nginx_default_https:
|
nginx_default_https:
|
||||||
{%- if 'nginx_default_https' in general.nginx and general.nginx.nginx_default_https and not 'revprox_client_external_domainnames' in general.revprox.revprox_client -%}
|
{%- if 'nginx_default_https' in general.nginx and general.nginx.nginx_default_https and not 'revprox_client_external_domainnames' in general.revprox.revprox_client -%}
|
||||||
true
|
true
|
||||||
{% else %}
|
{% else %}
|
||||||
false
|
false
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
<family name="reverse_proxy_for_" description="Serveur mandataire inverse pour " dynamic="nginx.remotes">
|
<family name="reverse_proxy_for_" description="Serveur mandataire inverse pour " dynamic="nginx.remotes">
|
||||||
<family name="reverse_proxy_" description="Reverse proxy " help="Paramètrage du proxy inverse" leadership="True">
|
<family name="reverse_proxy_" description="Reverse proxy " help="Paramètrage du proxy inverse" leadership="True">
|
||||||
<variable name="revprox_domainnames_" type="domainname" description="Nom des domaines auto-configurés dans le serveur mandataire inverse " multi="True" provider="ReverseProxy:external" hidden="True" mandatory="False"/>
|
<variable name="revprox_domainnames_" type="domainname" description="Nom des domaines auto-configurés dans le serveur mandataire inverse " multi="True" provider="ReverseProxy:external" hidden="True" mandatory="False"/>
|
||||||
<variable name="revprox_location_" type="filename" description="Répertoire ou nom de la page à rediriger pour " help="URL relative (sans le nom de domaine) redirigée pour l'adresse définie dans la variable ci-dessus (exemple "/mail")" mandatory="True" multi="True" provider="ReverseProxy:location"/>
|
<variable name="revprox_location_" type="filename" description="Répertoire ou nom de la page à rediriger pour " help="URL relative (sans le nom de domaine) redirigée pour l'adresse définie dans la variable ci-dessus (exemple "/mail")" mandatory="True" multi="True" unique="False" provider="ReverseProxy:location"/>
|
||||||
<variable name="revprox_url_" type="web_address" description="Domaine de destination ou URI complète pour " mandatory="True" help="Nom de domaine ou IP de destination, par exemple "http://domainelocal" ou URI, par exemple "http://domainelocal/dir/"" provider="ReverseProxy:url"/>
|
<variable name="revprox_url_" type="web_address" description="Domaine de destination ou URI complète pour " mandatory="True" unique="False" help="Nom de domaine ou IP de destination, par exemple "http://domainelocal" ou URI, par exemple "http://domainelocal/dir/"" provider="ReverseProxy:url"/>
|
||||||
<variable name="revprox_is_websocket_" type="boolean" description="Le point d'entrée est de types websocket pour " mandatory="True" multi="True" provider="ReverseProxy:websocket"/>
|
<variable name="revprox_is_websocket_" type="boolean" description="Le point d'entrée est de types websocket pour " mandatory="True" multi="True" unique="False" provider="ReverseProxy:websocket"/>
|
||||||
<variable name="revprox_max_body_size_" description="Taille maximum du corps pour " provider="ReverseProxy:max_body_size"/>
|
<variable name="revprox_max_body_size_" description="Taille maximum du corps pour " provider="ReverseProxy:max_body_size" unique="False"/>
|
||||||
<variable name="revprox_http_" type="boolean" description="Le site est en HTTP pour " provider="ReverseProxy:http"/>
|
<variable name="revprox_http_" type="boolean" description="Le site est en HTTP pour " provider="ReverseProxy:http" unique="False"/>
|
||||||
</family>
|
</family>
|
||||||
</family>
|
</family>
|
||||||
<variable name="revprox_domainnames" type="domainname" description="Nom des domaines auto-configurés dans le serveur mandataire inverse" multi="True" hidden="True" mandatory="False"/>
|
<variable name="revprox_domainnames" type="domainname" description="Nom des domaines auto-configurés dans le serveur mandataire inverse" multi="True" hidden="True" mandatory="False"/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
address: {{ ip_eth0 }}
|
address: {{ general.network.interface_0.ip_eth0 }}
|
||||||
urls:
|
urls:
|
||||||
{% for domain in nginx.remotes }}
|
{% for domain in nginx.remotes %}
|
||||||
{% set suffix = domain|normalize_family %}
|
{% set suffix = domain|normalize_family %}
|
||||||
{% for revprox in nginx['reverse_proxy_for_' + suffix]['reverse_proxy_' + suffix]['revprox_domainnames_' + suffix] %}
|
{% for revprox in nginx['reverse_proxy_for_' + suffix]['reverse_proxy_' + suffix]['revprox_domainnames_' + suffix] %}
|
||||||
{% for location in revprox['revprox_location_' + suffix] %}
|
{% for location in revprox['revprox_location_' + suffix] %}
|
||||||
|
@ -10,4 +10,4 @@ urls:
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
ca_certificate: ../etc/pki/ca-trust/source/anchors/ca_External.crt
|
ca_certificate: ../etc/pki/ca-trust/source/anchors/External.crt
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
<rougail version="0.10">
|
<rougail version="0.10">
|
||||||
<variables>
|
<variables>
|
||||||
<family name="dns_server" description="Serveur DNS">
|
<family name="dns_server" description="Serveur DNS">
|
||||||
<variable name="nsd_allowed_client" type="domainname" description="Clients" multi="True" hidden="True" provider="LocalDNS"/>
|
<variable name="nsd_allowed_clients" type="domainname" description="Clients" multi="True" hidden="True" provider="LocalDNS"/>
|
||||||
|
<family name="nsd_client_" dynamic="nsd_allowed_clients">
|
||||||
|
<variable name="nsd_dnssec_ds_" supplier="LocalDNS:DNSSEC_DS" hidden="True" multi="True"/>
|
||||||
|
</family>
|
||||||
<variable name="nsd_allowed_client_ip" type="ip" description="Clients" multi="True" hidden="True"/>
|
<variable name="nsd_allowed_client_ip" type="ip" description="Clients" multi="True" hidden="True"/>
|
||||||
<variable name="nsd_resolver" redefine="True" supplier="ExternalDNS"/>
|
<variable name="nsd_resolver" redefine="True" supplier="ExternalDNS"/>
|
||||||
<variable name="nsd_resolve_ip" type="ip" hidden="True"/>
|
<variable name="nsd_resolve_ip" type="ip" hidden="True"/>
|
||||||
|
@ -11,7 +14,7 @@
|
||||||
<constraints>
|
<constraints>
|
||||||
<fill name="get_ip">
|
<fill name="get_ip">
|
||||||
<param type="information">zones</param>
|
<param type="information">zones</param>
|
||||||
<param type="variable">nsd_allowed_client</param>
|
<param type="variable">nsd_allowed_clients</param>
|
||||||
<target>nsd_allowed_client_ip</target>
|
<target>nsd_allowed_client_ip</target>
|
||||||
</fill>
|
</fill>
|
||||||
<fill name="get_ip">
|
<fill name="get_ip">
|
||||||
|
@ -29,5 +32,10 @@
|
||||||
<param name="uniq" type="boolean">True</param>
|
<param name="uniq" type="boolean">True</param>
|
||||||
<target>nsd_reverse_network</target>
|
<target>nsd_reverse_network</target>
|
||||||
</fill>
|
</fill>
|
||||||
|
<fill name="get_dnssec_ds">
|
||||||
|
<param type="variable">domain_name_eth0</param>
|
||||||
|
<param type="variable">nsd_zones_all</param>
|
||||||
|
<target>nsd_dnssec_ds_</target>
|
||||||
|
</fill>
|
||||||
</constraints>
|
</constraints>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -38,3 +38,11 @@ root@debian:~# delv @192.168.45.11 -a keys +root=in.gnunux.info lemonldap.in.gnu
|
||||||
; fully validated
|
; fully validated
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# increase loglevel
|
||||||
|
|
||||||
|
echo """server:
|
||||||
|
debug-mode: yes
|
||||||
|
verbosity: 10
|
||||||
|
""" > /etc/nsd/conf.d/debug.conf
|
||||||
|
systemctl restart nsd
|
||||||
|
journalctl -fu nsd
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
<target type="variable">nsd.nsd_zone_.hostname_.ip_</target>
|
<target type="variable">nsd.nsd_zone_.hostname_.ip_</target>
|
||||||
</condition>
|
</condition>
|
||||||
<check name="valid_dns_hostname">
|
<check name="valid_dns_hostname">
|
||||||
|
<param type="suffix"/>
|
||||||
|
<param type="variable">nsd_zones_all</param>
|
||||||
<target>nsd.nsd_zone_.hostname_.hostname_</target>
|
<target>nsd.nsd_zone_.hostname_.hostname_</target>
|
||||||
</check>
|
</check>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
|
|
@ -145,8 +145,10 @@ def get_internal_info_in_zone(zones: list,
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
if type == 'host':
|
if type == 'host':
|
||||||
return list(zone['hosts'])
|
return list(['host'] + list(zone['hosts']))
|
||||||
return list(zone['hosts'].values())[index]
|
if not index:
|
||||||
|
return zone['host_ip']
|
||||||
|
return list(zone['hosts'].values())[index - 1]
|
||||||
|
|
||||||
|
|
||||||
def get_internal_zones(zones) -> _List[str]:
|
def get_internal_zones(zones) -> _List[str]:
|
||||||
|
@ -174,10 +176,35 @@ def calc_reverse_networks(names):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def valid_dns_hostname(hostname):
|
def valid_dns_hostname(hostname,
|
||||||
|
domainname,
|
||||||
|
zone_names,
|
||||||
|
):
|
||||||
if hostname != '*':
|
if hostname != '*':
|
||||||
try:
|
try:
|
||||||
DomainnameOption('a', '', hostname, type='hostname', allow_ip=False)
|
DomainnameOption('a', '', hostname, type='hostname', allow_ip=False)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
err.prefix = ''
|
err.prefix = ''
|
||||||
raise err from err
|
raise err from err
|
||||||
|
if hostname + '.' + domainname in zone_names:
|
||||||
|
raise ValueError(f'"{hostname}.{domainname}" is also a zone name')
|
||||||
|
|
||||||
|
|
||||||
|
@_multi_function
|
||||||
|
def get_dnssec_ds(cn: str,
|
||||||
|
names: str,
|
||||||
|
) -> str:
|
||||||
|
dnssec = []
|
||||||
|
for name in names:
|
||||||
|
if name.endswith('arpa.'):
|
||||||
|
name = name[:-1]
|
||||||
|
dir_name = _join(_PKI_DIR, cn, name, 'ksk')
|
||||||
|
filename = None
|
||||||
|
if _isdir(dir_name):
|
||||||
|
filenames = _glob(_join(dir_name, f'K{name}.+*.ds'))
|
||||||
|
if filenames:
|
||||||
|
filename = filenames[0]
|
||||||
|
if filename:
|
||||||
|
with open(filename) as fh:
|
||||||
|
dnssec.append(fh.read().strip())
|
||||||
|
return dnssec
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
address: '{{ ip_eth0 }}'
|
address: '{{ general.network.interface_0.ip_eth0 }}'
|
||||||
records:
|
records:
|
||||||
{% for domain in nsd_zones %}
|
{% for domain in nsd_zones %}
|
||||||
{% set suffix = domain|normalize_family
|
{% set suffix = domain|normalize_family %}
|
||||||
{% set hostnames = nsd["nsd_zone_" + suffix]["hostname_" + suffix]["hostname_" + suffix] %}
|
{% set hostnames = nsd["nsd_zone_" + suffix]["hostname_" + suffix]["hostname_" + suffix] %}
|
||||||
{% for hostname in hostnames %}
|
{% for hostname in hostnames %}
|
||||||
{% set type = hostname['type_' + suffix] %}
|
{% set type = hostname['type_' + suffix] %}
|
||||||
{% if type == 'A' %}
|
{% if type == 'A' %}
|
||||||
{{ hostname }}.{{ domain }}: '{{ hostname['ip_' + suffix] }}'
|
'{{ hostname }}.{{ domain }}': '{{ hostname['ip_' + suffix] }}'
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -31,8 +31,7 @@
|
||||||
<choice>HS512</choice>
|
<choice>HS512</choice>
|
||||||
<choice>RS256</choice>
|
<choice>RS256</choice>
|
||||||
</variable>
|
</variable>
|
||||||
<variable name="oauth2_client" description="Remote clients" type="domainname" provider="OAuth2Client"/>
|
<variable name="oauth2_server_domainname" type="domainname" description="OAuth2 server external domain name" mandatory='True' provider="OAuth2:external_domain"/>
|
||||||
<variable name="oauth2_server_domainname" type="domainname" description="OAuth2 server domain name" mandatory='True' provider="OAuth2Client:external_domain"/>
|
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
<constraints>
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
{% set username = "rougail_test@silique.fr" %}
|
{% set username = "rougail_test@silique.fr" %}
|
||||||
{% set username_family = "rougail_test@gnunux.info" %}
|
{% set username_family = "rougail_test@gnunux.info" %}
|
||||||
{% set name_family = 'gnunux' %}
|
{% set name_family = 'gnunux' %}
|
||||||
{% set familydn = ldapclient_base_dn|calc_ldapclient_base_dn(family_name=name_family) %}
|
{% set familydn = ldap_base_dn|calc_ldapclient_base_dn(family_name=name_family) %}
|
||||||
{% set userdn = 'cn=' + username + ',' + ldapclient_base_dn|calc_ldapclient_base_dn %}
|
{% set userdn = 'cn=' + username + ',' + ldap_base_dn|calc_ldapclient_base_dn %}
|
||||||
{% set userfamilydn = 'cn=' + username_family + ',' + familydn %}
|
{% set userfamilydn = 'cn=' + username_family + ',' + familydn %}
|
||||||
address: {{ general.network.ip_eth0 }}
|
address: {{ general.network.interface_0.ip_eth0 }}
|
||||||
admin_dn: {{ ldapclient_user }}
|
admin_dn: {{ ldap_user }}
|
||||||
admin_password: {{ general.ldap.client.ldapclient_user_password }}
|
admin_password: {{ general.ldap.ldap_user_password }}
|
||||||
user_dn: {{ userdn }}
|
user_dn: {{ userdn }}
|
||||||
user_password: {{ username|get_password(server_name='test', description='test', type="cleartext", hide=hide_secret, temporary=True) }}
|
user_password: {{ username|get_password(server_name='test', description='test', type="cleartext", hide=hide_secret, temporary=True) }}
|
||||||
user_family_dn: {{ userfamilydn }}
|
user_family_dn: {{ userfamilydn }}
|
||||||
user_family_password: {{ username_family|get_password(server_name='test', description="test", type="cleartext", hide=hide_secret, temporary=True)
|
user_family_password: {{ username_family|get_password(server_name='test', description="test", type="cleartext", hide=hide_secret, temporary=True) }}
|
||||||
base_account_dn: {{ ldap_account_dn }}
|
base_account_dn: {{ ldap_account_dn }}
|
||||||
base_user_dn: {{ ldapclient_user_dn }}
|
base_user_dn: {{ ldap_user_dn }}
|
||||||
base_family_dn: {{ familydn }}
|
base_family_dn: {{ familydn }}
|
||||||
base_group_dn: {{ ldapclient_group_dn }}
|
base_group_dn: {{ ldap_group_dn }}
|
||||||
{% for idx in range(3) %}
|
{% for idx in range(3) %}
|
||||||
{% set name = 'remote_test' + idx|string %}
|
{% set name = 'remote_test' + idx|string %}
|
||||||
remote{{ idx }}: cn={{ name }},{{ ldapclient_base_dn }}
|
remote{{ idx }}: cn={{ name }},{{ ldap_base_dn }}
|
||||||
remote_password{{ idx }}: {{ name|get_password(server_name=domain_name_eth0, description="remote account", type="cleartext", hide=hide_secret, temporary=True) }}
|
remote_password{{ idx }}: {{ name|get_password(server_name=domain_name_eth0, description="remote account", type="cleartext", hide=hide_secret, temporary=True) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
users:
|
users:
|
||||||
{{ username }}: {{ userdn }}
|
{{ username }}: {{ userdn }}
|
||||||
{{ username_family }}: {{ userfamilydn }}
|
{{ username_family }}: {{ userfamilydn }}
|
||||||
{% for user in accounts.users.ldap_user_mail %}
|
{% for user in accounts.users.ldap_user_mail %}
|
||||||
{{ user }}: cn={{ user }},{{ ldapclient_user_dn }}
|
{{ user }}: cn={{ user }},{{ ldap_user_dn }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for family in accounts.families %}
|
{% for family in accounts.families %}
|
||||||
{% set families = ldapclient_base_dn|calc_ldapclient_base_dn(family) %}
|
{% set families = ldap_base_dn|calc_ldapclient_base_dn(family) %}
|
||||||
{% for user in accounts['family_' + family]['users_' + family]['ldap_user_mail_' + family] %}
|
{% for user in accounts['family_' + family]['users_' + family]['ldap_user_mail_' + family] %}
|
||||||
{{ user }}: cn={{ user }},{{ families }}
|
{{ user }}: cn={{ user }},{{ families }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -36,19 +36,15 @@ groups:
|
||||||
users:
|
users:
|
||||||
- {{ userdn }}
|
- {{ userdn }}
|
||||||
{% for user in accounts.users.ldap_user_mail %}
|
{% for user in accounts.users.ldap_user_mail %}
|
||||||
- cn={{ user }},{{ ldapclient_user_dn }}
|
- cn={{ user }},{{ ldap_user_dn }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for family in accounts.families
|
{% for family in accounts.families %}
|
||||||
|
{% set families = ldap_base_dn|calc_ldapclient_base_dn(family) %}
|
||||||
{{ family }}:
|
{{ family }}:
|
||||||
{% if family == name_family }
|
{% if family == name_family %}
|
||||||
- {{ userfamilydn }}
|
- {{ userfamilydn }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for user in accounts['family_' + family]['users_' + family]['ldap_user_mail_' + family] %}
|
{%- for user in accounts['family_' + family]['users_' + family]['ldap_user_mail_' + family] %}
|
||||||
- cn={{ user }},{{ families }}
|
- cn={{ user }},{{ families }}
|
||||||
%end for
|
{% endfor %}
|
||||||
%end for
|
{% endfor %}
|
||||||
{% if 'gnunux' not in accounts.families %}
|
|
||||||
{% set families = ldapclient_base_dn|calc_ldapclient_base_dn('gnunux') %}
|
|
||||||
gnunux:
|
|
||||||
- cn=rougail_test@gnunux.info,{{ families }}
|
|
||||||
%end if
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ format: '0.1'
|
||||||
description: Peertube, a federated (ActivityPub) video streaming platform
|
description: Peertube, a federated (ActivityPub) video streaming platform
|
||||||
website: https://www.openldap.org/
|
website: https://www.openldap.org/
|
||||||
depends:
|
depends:
|
||||||
- base-fedora-36
|
- base-fedora-38
|
||||||
- dns-external
|
- dns-external
|
||||||
- postgresql-client
|
- postgresql-client
|
||||||
- relay-mail-client
|
- relay-mail-client
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
PKG="$PKG peertube peertube-tools yarnpkg"
|
#PKG="$PKG peertube peertube-tools yarnpkg"
|
||||||
#PKG="$PKG peertube yarnpkg"
|
PKG="$PKG peertube yarnpkg"
|
||||||
COPR="https://copr.fedorainfracloud.org/coprs/daftaupe/peertube/repo/fedora-36/daftaupe-peertube-fedora-36.repo"
|
COPR="https://copr.fedorainfracloud.org/coprs/daftaupe/peertube/repo/fedora-$RELEASEVER/daftaupe-peertube-fedora-$RELEASEVER.repo"
|
||||||
FUSION=true
|
FUSION=true
|
||||||
|
|
|
@ -12,15 +12,14 @@
|
||||||
<variables>
|
<variables>
|
||||||
<family name="prometheus">
|
<family name="prometheus">
|
||||||
<variable name="client_addresses" type="domainname" provider="Prometheus" multi="True"/>
|
<variable name="client_addresses" type="domainname" provider="Prometheus" multi="True"/>
|
||||||
<variable name="client_ip_addresses" type="ip" multi="True" provider="Prometheus:address" mandatory="False"/>
|
<variable name="listen_addresses" type="ip" hidden="True" multi="True"/>
|
||||||
<variable name="listen_address" type="ip" hidden="True"/>
|
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
<constraints>
|
||||||
<fill name="get_ip">
|
<fill name="get_ip">
|
||||||
<param type="information">zones</param>
|
<param type="information">zones</param>
|
||||||
<param type="information" variable="providers">Prometheus</param>
|
<param type="variable">client_addresses</param>
|
||||||
<target>listen_address</target>
|
<target>listen_addresses</target>
|
||||||
</fill>
|
</fill>
|
||||||
</constraints>
|
</constraints>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
# Additional command-line arguments to pass to the server.
|
# Additional command-line arguments to pass to the server.
|
||||||
#>GNUNUX
|
#>GNUNUX
|
||||||
#ARGS="--web.listen-address=127.0.0.1:9090"
|
#ARGS="--web.listen-address=127.0.0.1:9090"
|
||||||
ARGS="--web.listen-address={{ general.prometheus.listen_address }}:9090"
|
ARGS="
|
||||||
|
{%- for address in general.prometheus.listen_addresses -%}
|
||||||
|
--web.listen-address={{ address }}:9090
|
||||||
|
{%- endfor -%}
|
||||||
|
"
|
||||||
#<GNUNUX
|
#<GNUNUX
|
||||||
|
|
|
@ -32,6 +32,6 @@ scrape_configs:
|
||||||
{% for node in general.prometheus.client_addresses %}
|
{% for node in general.prometheus.client_addresses %}
|
||||||
- job_name: "{{ node }}"
|
- job_name: "{{ node }}"
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: ["{{ general.prometheus.client_ip_addresses[loop.index - 1] }}:9090"]
|
- targets: ["{{ node }}:9090"]
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
#<GNUNUX
|
#<GNUNUX
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
<variable name="redis_client_server_domainname" type="domainname" description="Nom de domaine du serveur Redis" mandatory="True" supplier="Redis"/>
|
<variable name="redis_client_server_domainname" type="domainname" description="Nom de domaine du serveur Redis" mandatory="True" supplier="Redis"/>
|
||||||
<variable name="redis_client_username" description="Nom d'utilisateur" mandatory="True" supplier="Redis:username"/>
|
<variable name="redis_client_username" description="Nom d'utilisateur" mandatory="True" supplier="Redis:username"/>
|
||||||
<variable name="redis_client_password" type="password" description="Mot de passe de connexion" mandatory="True" supplier="Redis:password"/>
|
<variable name="redis_client_password" type="password" description="Mot de passe de connexion" mandatory="True" supplier="Redis:password"/>
|
||||||
<variable name="redis_server" description="Remote" type="domainname" multi="True" provider="RedisClient" hidden="True"/>
|
<variable name="redis_client_index" type="number" description="Redis index" mandatory='True' provider="Redis:index"/>
|
||||||
<variable name="redis_client_index" type="number" description="Redis index" mandatory='True' provider="RedisClient:index"/>
|
|
||||||
<variable name="redis_client_key_owner" type="unix_user" description="Key owner" mandatory="True" hidden="True">
|
<variable name="redis_client_key_owner" type="unix_user" description="Key owner" mandatory="True" hidden="True">
|
||||||
<value>apache</value>
|
<value>apache</value>
|
||||||
</variable>
|
</variable>
|
||||||
|
|
|
@ -4,17 +4,12 @@
|
||||||
<variable name="remotes" type="domainname" provider="Redis" mandatory="True" multi="True" hidden="True"/>
|
<variable name="remotes" type="domainname" provider="Redis" mandatory="True" multi="True" hidden="True"/>
|
||||||
<family name="remote_" dynamic="accounts.remotes">
|
<family name="remote_" dynamic="accounts.remotes">
|
||||||
<variable name="ip_" type="ip" mandatory="True"/>
|
<variable name="ip_" type="ip" mandatory="True"/>
|
||||||
<variable name="client_" type="domainname" mandatory="True" supplier="RedisClient"/>
|
|
||||||
<variable name="username_" hidden="True" mandatory="True" provider="Redis:username"/>
|
<variable name="username_" hidden="True" mandatory="True" provider="Redis:username"/>
|
||||||
<variable name="password_" hidden="True" type="password" mandatory="True" provider="Redis:password"/>
|
<variable name="password_" hidden="True" type="password" mandatory="True" provider="Redis:password"/>
|
||||||
<variable name="index_" hidden="True" type="number" mandatory="True" supplier="RedisClient:index"/>
|
<variable name="index_" hidden="True" type="number" mandatory="True" supplier="Redis:index"/>
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
<constraints>
|
||||||
<fill name="calc_value">
|
|
||||||
<param type="suffix"/>
|
|
||||||
<target>accounts.remote_.client_</target>
|
|
||||||
</fill>
|
|
||||||
<fill name="get_ip">
|
<fill name="get_ip">
|
||||||
<param type="information">zones</param>
|
<param type="information">zones</param>
|
||||||
<param type="suffix"/>
|
<param type="suffix"/>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<services>
|
<services>
|
||||||
<service name="revprox" manage="False">
|
<service name="revprox" manage="False">
|
||||||
<certificate server="revprox_client_server_domainname" authority="InternalReverseProxy" owner="revprox_client_cert_owner" owner_type="variable" type="server">revprox</certificate>
|
<certificate server="revprox_client_server_domainname" authority="InternalReverseProxy" owner="revprox_client_cert_owner" owner_type="variable" type="server">revprox</certificate>
|
||||||
<file engine="ansible" filelist="copy_tests">/tests/reverse-proxy.yml</file>
|
<file engine="ansible" filelist="copy_tests">/tests/reverse-proxy-client.yml</file>
|
||||||
</service>
|
</service>
|
||||||
</services>
|
</services>
|
||||||
<variables>
|
<variables>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
ca_certificate: ../../{{ revprox_client_server_domainname.split('.', 1)[0] }}.*/etc/pki/ca-trust/source/anchors/ca_External.crt
|
ca_certificate: ../../{{ revprox_client_server_domainname.split('.', 1)[0] }}.*/etc/pki/ca-trust/source/anchors/External.crt
|
|
@ -42,7 +42,7 @@ class Authentication:
|
||||||
try:
|
try:
|
||||||
ret = req.get(url, verify=VERIFY)
|
ret = req.get(url, verify=VERIFY)
|
||||||
except SSLError:
|
except SSLError:
|
||||||
conf_file = f'{environ["MACHINE_TEST_DIR"]}/reverse-proxy.yml'
|
conf_file = f'{environ["MACHINE_TEST_DIR"]}/reverse-proxy-client.yml'
|
||||||
with open(conf_file) as yaml:
|
with open(conf_file) as yaml:
|
||||||
data = load(yaml, Loader=SafeLoader)
|
data = load(yaml, Loader=SafeLoader)
|
||||||
path = join(environ["MACHINE_TEST_DIR"], data["ca_certificate"])
|
path = join(environ["MACHINE_TEST_DIR"], data["ca_certificate"])
|
|
@ -4,3 +4,4 @@ website: https://systemd.io/
|
||||||
depends:
|
depends:
|
||||||
- base-machine
|
- base-machine
|
||||||
- journald
|
- journald
|
||||||
|
- resolved
|
||||||
|
|
|
@ -23,5 +23,6 @@ Gateway={{ gateway }}
|
||||||
{% set dns = general.network.ip_dns %}
|
{% set dns = general.network.ip_dns %}
|
||||||
{% if dns %}
|
{% if dns %}
|
||||||
DNS={{ dns }}
|
DNS={{ dns }}
|
||||||
|
LLMNR=no
|
||||||
ConfigureWithoutCarrier=yes
|
ConfigureWithoutCarrier=yes
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -20,9 +20,9 @@ remote-control:
|
||||||
|
|
||||||
{% for authority in general.dns_resolver.forward_zones.unbound_forward_address %}
|
{% for authority in general.dns_resolver.forward_zones.unbound_forward_address %}
|
||||||
{% for zone in authority.unbound_forward_zones %}
|
{% for zone in authority.unbound_forward_zones %}
|
||||||
forward-zone:
|
stub-zone:
|
||||||
name: "{{ zone }}"
|
name: "{{ zone }}"
|
||||||
forward-addr: {{ authority.unbound_allowed_client }}
|
stub-addr: {{ authority.unbound_allowed_client }}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -31,4 +31,3 @@ forward-zone:
|
||||||
{% for forward in general.dns_resolver.unbound_default_forwards %}
|
{% for forward in general.dns_resolver.unbound_default_forwards %}
|
||||||
forward-addr: {{ forward }}
|
forward-addr: {{ forward }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
# forward-first: no
|
|
||||||
|
|
|
@ -712,30 +712,32 @@ server:
|
||||||
# local-zone: "onion." nodefault
|
# local-zone: "onion." nodefault
|
||||||
# local-zone: "test." nodefault
|
# local-zone: "test." nodefault
|
||||||
# local-zone: "invalid." nodefault
|
# local-zone: "invalid." nodefault
|
||||||
# local-zone: "10.in-addr.arpa." nodefault
|
#>GNUNUX
|
||||||
# local-zone: "16.172.in-addr.arpa." nodefault
|
local-zone: "10.in-addr.arpa." nodefault
|
||||||
# local-zone: "17.172.in-addr.arpa." nodefault
|
local-zone: "16.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "18.172.in-addr.arpa." nodefault
|
local-zone: "17.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "19.172.in-addr.arpa." nodefault
|
local-zone: "18.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "20.172.in-addr.arpa." nodefault
|
local-zone: "19.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "21.172.in-addr.arpa." nodefault
|
local-zone: "20.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "22.172.in-addr.arpa." nodefault
|
local-zone: "21.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "23.172.in-addr.arpa." nodefault
|
local-zone: "22.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "24.172.in-addr.arpa." nodefault
|
local-zone: "23.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "25.172.in-addr.arpa." nodefault
|
local-zone: "24.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "26.172.in-addr.arpa." nodefault
|
local-zone: "25.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "27.172.in-addr.arpa." nodefault
|
local-zone: "26.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "28.172.in-addr.arpa." nodefault
|
local-zone: "27.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "29.172.in-addr.arpa." nodefault
|
local-zone: "28.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "30.172.in-addr.arpa." nodefault
|
local-zone: "29.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "31.172.in-addr.arpa." nodefault
|
local-zone: "30.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "168.192.in-addr.arpa." nodefault
|
local-zone: "31.172.in-addr.arpa." nodefault
|
||||||
# local-zone: "0.in-addr.arpa." nodefault
|
local-zone: "168.192.in-addr.arpa." nodefault
|
||||||
# local-zone: "254.169.in-addr.arpa." nodefault
|
local-zone: "0.in-addr.arpa." nodefault
|
||||||
# local-zone: "2.0.192.in-addr.arpa." nodefault
|
local-zone: "254.169.in-addr.arpa." nodefault
|
||||||
# local-zone: "100.51.198.in-addr.arpa." nodefault
|
local-zone: "2.0.192.in-addr.arpa." nodefault
|
||||||
# local-zone: "113.0.203.in-addr.arpa." nodefault
|
local-zone: "100.51.198.in-addr.arpa." nodefault
|
||||||
# local-zone: "255.255.255.255.in-addr.arpa." nodefault
|
local-zone: "113.0.203.in-addr.arpa." nodefault
|
||||||
|
local-zone: "255.255.255.255.in-addr.arpa." nodefault
|
||||||
|
#<GNUNUX
|
||||||
# local-zone: "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
|
# local-zone: "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
|
||||||
# local-zone: "d.f.ip6.arpa." nodefault
|
# local-zone: "d.f.ip6.arpa." nodefault
|
||||||
# local-zone: "8.e.f.ip6.arpa." nodefault
|
# local-zone: "8.e.f.ip6.arpa." nodefault
|
||||||
|
|
|
@ -5,4 +5,4 @@ username: {{ username }}
|
||||||
password: {{ username|get_password(server_name=general.network.interface_0.domain_name_eth0, description='test', type="cleartext", hide=general.hide_secret, temporary=False) }}
|
password: {{ username|get_password(server_name=general.network.interface_0.domain_name_eth0, description='test', type="cleartext", hide=general.hide_secret, temporary=False) }}
|
||||||
privkey: {{ srv_dir }}/vaultwarden/rsa_key.pem
|
privkey: {{ srv_dir }}/vaultwarden/rsa_key.pem
|
||||||
uuid: {{ general.vaultwarden.vaultwarden_test_device_identifier }}
|
uuid: {{ general.vaultwarden.vaultwarden_test_device_identifier }}
|
||||||
revprox_ip: {{ general.revprox.revprox_client.revprox_client_server_ip }}
|
revprox_ip: {{ general.revprox.revprox_client_server_ip }}
|
||||||
|
|
|
@ -11,18 +11,11 @@
|
||||||
<variables>
|
<variables>
|
||||||
<family name="vector" description="loki">
|
<family name="vector" description="loki">
|
||||||
<variable name="client_addresses" type="domainname" provider="Vector" multi="True"/>
|
<variable name="client_addresses" type="domainname" provider="Vector" multi="True"/>
|
||||||
<variable name="listen_address" type="ip" hidden="True"/>
|
<variable name="listen_addresses" type="ip" hidden="True" multi="True" provider="Vector:address"/>
|
||||||
</family>
|
</family>
|
||||||
<family name="loki" description="loki">
|
<family name="loki" description="loki">
|
||||||
<variable name="server_domainname" type="domainname" supplier="Loki" mandatory="True"/>
|
<variable name="server_domainname" type="domainname" supplier="Loki" mandatory="True"/>
|
||||||
</family>
|
</family>
|
||||||
</variables>
|
</variables>
|
||||||
<constraints>
|
|
||||||
<fill name="get_ip">
|
|
||||||
<param type="information">zones</param>
|
|
||||||
<param type="information" variable="providers">Vector</param>
|
|
||||||
<target>listen_address</target>
|
|
||||||
</fill>
|
|
||||||
</constraints>
|
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,9 @@ data_dir = "/srv/vector"
|
||||||
{% if general.vector.client_addresses %}
|
{% if general.vector.client_addresses %}
|
||||||
[sources.vector_client]
|
[sources.vector_client]
|
||||||
type = "vector"
|
type = "vector"
|
||||||
address = "{{ general.vector.listen_address }}:8686"
|
{% for address in general.vector.listen_addresses %}
|
||||||
|
address = "{{ address }}:8686"
|
||||||
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[sources.remote_journal]
|
[sources.remote_journal]
|
||||||
|
|
Loading…
Reference in a new issue