Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
07947ab446 | |||
442a5c515f | |||
7c970d1521 | |||
3b6f236602 | |||
47a1d93547 | |||
089a0ed11c | |||
33a035cf6b | |||
1e8f3901d4 | |||
b0619f4b8f | |||
82b8f535bb | |||
f89212b1cb | |||
93d40b7432 | |||
3ed00b733e |
2
.cz.yaml
2
.cz.yaml
@ -4,5 +4,5 @@ commitizen:
|
||||
prerelease_offset: 1
|
||||
tag_format: $version
|
||||
update_changelog_on_bump: false
|
||||
version: 0.2.0
|
||||
version: 0.4.0
|
||||
version_scheme: semver
|
||||
|
@ -19,18 +19,8 @@ variables:
|
||||
DOCKER_IMAGE_PUBLISH_REGISTRY: docker.io/nofusscomputing
|
||||
DOCKER_IMAGE_PUBLISH_URL: https://hub.docker.com/r/nofusscomputing/$DOCKER_IMAGE_PUBLISH_NAME
|
||||
|
||||
RELEASE_ADDITIONAL_ACTIONS_BUMP: |
|
||||
sed -E "/http_agent: nfc-phpipam-scan-agent/s/\/(.+)/\/$(cz version --project)/g" -i playbooks/tasks/scan_subnet.yaml;
|
||||
RELEASE_ADDITIONAL_ACTIONS_BUMP: ./.gitlab/additional_actions_bump.sh
|
||||
|
||||
git add playbooks/tasks/scan_subnet.yaml;
|
||||
|
||||
git status;
|
||||
|
||||
sed -E "/http_agent: nfc-phpipam-scan-agent/s/\/(.+)/\/$(cz version --project)/g" -i playbooks/tasks/api_call.yaml
|
||||
|
||||
git add playbooks/tasks/api_call.yaml;
|
||||
|
||||
git status;
|
||||
|
||||
include:
|
||||
|
||||
@ -40,6 +30,7 @@ include:
|
||||
ref: development
|
||||
file:
|
||||
- .gitlab-ci_common.yaml
|
||||
- conventional_commits/.gitlab-ci.yml
|
||||
- template/ansible-collection.gitlab-ci.yaml
|
||||
- template/mkdocs-documentation.gitlab-ci.yaml
|
||||
# ToDo: update gitlabCI jobs for collections workflow
|
||||
|
13
.gitlab/additional_actions_bump.sh
Normal file
13
.gitlab/additional_actions_bump.sh
Normal file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
sed -E "/http_agent: nfc-phpipam-scan-agent/s/\/(.+)/\/$(cz version --project)/g" -i playbooks/tasks/scan_subnet.yaml;
|
||||
|
||||
git add playbooks/tasks/scan_subnet.yaml;
|
||||
|
||||
git status;
|
||||
|
||||
sed -E "/http_agent: nfc-phpipam-scan-agent/s/\/(.+)/\/$(cz version --project)/g" -i playbooks/tasks/api_call.yaml;
|
||||
|
||||
git add playbooks/tasks/api_call.yaml;
|
||||
|
||||
git status;
|
23
CHANGELOG.md
23
CHANGELOG.md
@ -1,3 +1,22 @@
|
||||
## 0.4.0 (2024-02-26)
|
||||
|
||||
### Feat
|
||||
|
||||
- **docker**: update trusted CA certificates on start
|
||||
- **docker**: add trace output to determine install path for package
|
||||
|
||||
## 0.3.0 (2024-02-25)
|
||||
|
||||
### Feat
|
||||
|
||||
- **server**: DNS Reverse Lookup for IP Address'
|
||||
- **server**: Convert scanned time within scan report to UTC
|
||||
|
||||
### Fix
|
||||
|
||||
- **ci**: http user_agent version set during version bump
|
||||
- **server**: Time of last access for scan agent to use 'now'
|
||||
|
||||
## 0.2.0 (2024-02-24)
|
||||
|
||||
### Feat
|
||||
@ -22,8 +41,6 @@
|
||||
|
||||
- **server**: use correct sql syntax to insert ipaddress
|
||||
- **agent**: only attempt to scan subnet if subnets were returned
|
||||
- **agent**: cater for api call that returns nothing
|
||||
- **docker**: ensure correct variable used to install package
|
||||
- **build**: ensure the correct tags and architectures are published
|
||||
|
||||
### Refactor
|
||||
@ -48,5 +65,3 @@
|
||||
- **ci**: ensure docker publish uses correct tag
|
||||
- **ci**: ensure correct github sync repo is used
|
||||
- **ci**: ensure docker build and publish occurs
|
||||
- Don't process results if scan report is empty
|
||||
- **docs**: correct nav link
|
||||
|
@ -92,21 +92,24 @@ COPY includes/ /
|
||||
|
||||
RUN mkdir -p /tmp/collection; \
|
||||
if [ "$COLLECTION_PACKAGE" != "dev" ]; then \
|
||||
echo "specified"; \
|
||||
echo "[TRACE] Package Specified"; \
|
||||
ansible-galaxy collection install --force-with-deps --pre \
|
||||
$COLLECTION_PACKAGE; \
|
||||
elif [ "$COLLECTION_PACKAGE" == "dev" ]; then \
|
||||
echo "[TRACE] Development Build"; \
|
||||
git clone \
|
||||
--depth=1 \
|
||||
-b $COLLECTION_BRANCH \
|
||||
https://gitlab.com/nofusscomputing/projects/ansible/collections/phpipam_scan_agent.git \
|
||||
/tmp/collection; \
|
||||
if [ "${COLLECTION_COMMIT}" != "none" ]; then git switch $COLLECTION_COMMIT; fi; \
|
||||
echo "[TRACE] Installing Development Build"; \
|
||||
ansible-galaxy collection install --force-with-deps --pre \
|
||||
/tmp/collection/.; \
|
||||
rm -Rf /tmp/collection; \
|
||||
fi; \
|
||||
chmod +x /etc/cron.d/*; \
|
||||
chmod +x /bin/update-ca; \
|
||||
chown root:root -R /etc/phpipam; \
|
||||
chmod 740 -R /etc/phpipam;
|
||||
|
||||
|
@ -22,6 +22,7 @@ docker run \
|
||||
-p "5000:5000" \
|
||||
-v "./scan_agent.yaml:/etc/phpipam/scan_agent.yaml" \
|
||||
-v "./scan_server.yaml:/etc/phpipam/scan_server.yaml" \
|
||||
-v "./my-custom-ca.crt:/usr/local/share/ca-certificates/my-custom-ca.crt:ro"
|
||||
--name scan-agent \
|
||||
nofusscomputing/phpipam-scan-agent:latest;
|
||||
|
||||
@ -37,9 +38,16 @@ When viewing the container logs `docker logs <container name>`, what you will se
|
||||
During the build of the container environmental variable `ANSIBLE_FORCE_COLOR='true'` is set, this enables the playbooks to be in colour when viewing the container logs. If this is not desired, set the variable to `ANSIBLE_FORCE_COLOR='false'` when launching the container.
|
||||
|
||||
|
||||
### Custom CA Certificate
|
||||
|
||||
When the container starts or restarts a script runs that updates the containers trusted CA certificates. Details for mounting a/an certificate(s) is detailed below.
|
||||
|
||||
|
||||
### Volumes
|
||||
|
||||
You will need to configure the scan components:
|
||||
To configure the components, the following files will need to be mounted within the container:
|
||||
|
||||
- Custom CA certificate at path `/usr/local/share/ca-certificates/`. you can mount a single `crt` file or multiple if you use a sub-directory at this path.
|
||||
|
||||
- scanner config file at path `/etc/phpipam/scan_agent.yaml`, see [scanner docs](scanner.md#variables) for details.
|
||||
|
||||
|
@ -25,6 +25,8 @@ A phpIPAM scan agent designed for both local and remote network scanning. This A
|
||||
|
||||
This collection has been broken down into two components, a [server](server.md) and a [scanner](scanner.md). The scanner as the name implies will scan the networks assigned to it by phpIPAM and on completing a scan of a subnet, will post the results to the Server component which will process the results, and update the phpIPAM MySQL/MariaDB database directly.
|
||||
|
||||
This agent has been created to solve a few shortcomings of the official scan-agent. Ansible was chosen as the tool for the creation of the scan-agent. This was done as it lowers the bar of entry to modifying and development. This as well as that Ansible is a mature automation system that has many modules. The latter offers a wide range of integrating different systems. The scanner component is just an ansible playbook, whilst the server is an ansilbe rulebook which is based upon Event Driven Ansible (EDA).
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
@ -32,6 +34,8 @@ This collection is available on Ansible Galaxy and can be installed with `ansibl
|
||||
|
||||
Prefer to use our [docker](docker.md) image? It's available on Docker Hub `docker pull nofusscomputing/phpipam-scan-agent:latest`.
|
||||
|
||||
There is no timezone support within phpIPAM. Due to this it's recommended that you setup phpIPAM, the database and the scanner component to use UTC (GMT +00:00) timezone or that all components be setup to use the same timezone.
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
@ -50,9 +54,11 @@ The following features are available or planned to be implmented:
|
||||
!!! info
|
||||
It's only possible to obtain a MAC Address if the scanner is on the same L2 network (Broadcast Domain). Within the docs you will find the different methods available to achieve this.
|
||||
|
||||
- Remote Network Scanning
|
||||
- [Remote Network Scanning](scanner.md#remote-network-scannning)
|
||||
|
||||
- [**ToDo** Resolve DNS names](https://gitlab.com/nofusscomputing/projects/ansible/collections/phpipam_scan_agent/-/issues/4)
|
||||
- [Resolve DNS names](index.md#resolve-dns-names)
|
||||
|
||||
- [Timezone Normalization](server.md#timezone-normalization)
|
||||
|
||||
|
||||
## phpIPAM Features
|
||||
@ -75,6 +81,16 @@ When this setting is enabled, the scanner will scan the entire subnet that has b
|
||||
This is displayed within the subnet interface next to the `Discover new hosts` field. Whenever a scan report is received by the server this filed is updated to reflect the last scan time.
|
||||
|
||||
|
||||
### Resolve DNS names
|
||||
|
||||
- Location `Subnet -> Resolve DNS names`
|
||||
|
||||
When this setting is enabled, DNS resolution for the hostname for any IP found will be conducted. If you have setup nameservers (`Administration -> Nameservers`) and assigned them to the subnet, they will be used for name resolution. If no nameservers are configured for the subnet, the host's nameservers where the scanner is running from will be used. BY default within phpIPAM, DNS Resolution is turned off for a subnet and as such the scanner will not resolve IP address DNS names.
|
||||
|
||||
!!! info
|
||||
The FQDN for an IP that is retured is not used as the hostname. **Only** the first octet. i.e. if the reverse DNS lookup returns a FQDN of `my_hostname.domainname.tld`, the hostname for the IP address will be set to `my_hostname`
|
||||
|
||||
|
||||
### Scan Agent
|
||||
|
||||
- Location `Administration -> Scan agents [Last access]`
|
||||
|
@ -6,12 +6,12 @@ template: project.html
|
||||
about: https://gitlab.com/nofusscomputing/projects/ansible/collections/phpipam_scan_agent
|
||||
---
|
||||
|
||||
The Scan Agent Scanner component is intended to scan networks that are assigned to it by the phpIPAM server. It can be installed and ran from any host that is capable of running python.
|
||||
The Scan Agent Scanner component is intended to scan networks that are assigned to it by the phpIPAM server. It can be installed and ran from any host that is capable of running python. The scan agent only requires that there be `nmap` installed as this is the package that conducts the network scanning.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
After installing the collection and configuring. Running the agent is as simple as running the following command:
|
||||
Ensure that the `namp` package is installed, install and configure the collection. Running the agent is as simple as running the following command:
|
||||
|
||||
``` bash
|
||||
|
||||
@ -100,7 +100,7 @@ The scanner component has the following workflow:
|
||||
|
||||
Once the [server component](server.md#remote-network-scannning) has been setup, the client can be installed/used from any network. Even a network that is isolated from the server. Only caveat is that the client can communicate with the server. To ensure that the client can connect to the server set the `auth_token` to match that of the server.
|
||||
|
||||
There is no true confirmation of the servers identity outside of confirming the TLS Certificate is trusted. Due to this fact, you're advised to use your own CA to sign the server components TLS Certificate. By doing this only you can issue a certificate to the server component. All that is required is to ensure that your CA certificate is within the trusted certificates of the machine that is running the agent.
|
||||
There is no true confirmation of the servers identity outside of confirming the TLS Certificate is trusted. Due to this fact, you're advised to use your own CA to sign the server components TLS Certificate. By doing this only you can issue a certificate to the server component. All that is required is to ensure that [your CA certificate](docker.md#custom-ca-certificate) is within the [trusted certificates](../../../itil/runbooks/linux/custom_ca.md) of the machine that is running the agent.
|
||||
|
||||
!!! danger "Security"
|
||||
Failing to secure the server component communication with TLS will allow anyone with direct access to the line of communication to view the `auth_token`. Anyone who has the `auth_token` will be able to upload data to the server.
|
||||
|
@ -61,9 +61,13 @@ The Server componet has the following workflow:
|
||||
|
||||
## Remote network Scannning
|
||||
|
||||
Remote network scanning is possible with the Scan-Agent. The server must be setup and have connectivity to the phpIPAM MariaDB/MySQL database. Currently the server does not perform secure communication. As such you are strongly encouraged to setup the server component behind a reverse proxy that conducts the TLS termination.
|
||||
Remote network scanning is possible with the Scan-Agent. The server must be setup and have connectivity to the phpIPAM MariaDB/MySQL database. Currently the server does not perform secure communication. As such you are strongly encouraged to setup the server component behind a reverse proxy that conducts the TLS termination. It's also recommended that you use your [own CA](docker.md#custom-ca-certificate) to sign the TLS certificate. Just don't forget to add this CA certificate to the [trusted CA certificates](../../../itil/runbooks/linux/custom_ca.md)
|
||||
|
||||
The [scan](scanner.md#remote-network-scannning) and server component must be setup with the same `auth_token`. It is this token that provides a means to ensure that what the server is receiving, is from an authorized client.
|
||||
|
||||
!!! danger "Security"
|
||||
Failing to secure the server component communication with TLS will allow anyone with direct access to the line of communication to view the `auth_token`. Anyone who has the `auth_token` will be able to upload data to the server.
|
||||
|
||||
## Timezone normalization
|
||||
|
||||
As there is no support within phpIPAM for different timezones. The server component when receiving updates from scanners, will convert any time found to UTC (GMT +00:00). This is required so that phpIPAM features that rely on time, function as they should. This setup requires that machine or docker containers for phpIPAM and the MySQL/MariaDB database both have their timezones set to UTC. If you don't wish for any timezone conversion to be done, ensure that where ever all components, including the scan server component, share the same timezone.
|
||||
|
1
docs/projects/itil/runbooks/linux/custom_ca.md
Normal file
1
docs/projects/itil/runbooks/linux/custom_ca.md
Normal file
@ -0,0 +1 @@
|
||||
linked page
|
@ -8,7 +8,7 @@ namespace: nofusscomputing
|
||||
name: phpipam_scan_agent
|
||||
|
||||
# The version of the collection. Must be compatible with semantic versioning
|
||||
version: 0.2.0
|
||||
version: 0.4.0
|
||||
|
||||
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
|
||||
readme: README.md
|
||||
|
Submodule gitlab-ci updated: 6f80ea3af7...41eeb7badd
40
includes/bin/update-ca
Executable file
40
includes/bin/update-ca
Executable file
@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e;
|
||||
|
||||
run_command() {
|
||||
|
||||
command_date=$(date '+%Y-%m-%d %H:%M:%S');
|
||||
|
||||
echo "${command_date} - info - $1 - $2";
|
||||
|
||||
$1
|
||||
|
||||
if [ $? ]; then
|
||||
|
||||
echo "${command_date} - info - $1 - command ran without error. exit=$?";
|
||||
|
||||
else
|
||||
|
||||
echo "${command_date} - error - ${1} - command had an error. exit=$?";
|
||||
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
while :
|
||||
do
|
||||
|
||||
run_command "ls -lR /usr/local/share/ca-certificates/" "List custom CA Certificates";
|
||||
|
||||
|
||||
run_command "update-ca-certificates --fresh" "Clear currently trusted CA Certificates";
|
||||
|
||||
|
||||
run_command "update-ca-certificates" "Update trusted CA Certificates";
|
||||
|
||||
|
||||
sleep 9999999999999;
|
||||
|
||||
done;
|
@ -0,0 +1,8 @@
|
||||
[program:trusted-ca-update]
|
||||
startsecs=0
|
||||
stopwaitsecs=55
|
||||
command=/bin/update-ca
|
||||
autorestart=true
|
||||
autostart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
@ -82,3 +82,4 @@
|
||||
api_address: addresses
|
||||
api_subnets: subnets
|
||||
api_scanagents: tools/scanagents
|
||||
api_nameservers: tools/nameservers
|
||||
|
@ -63,7 +63,7 @@
|
||||
{%- endif %}
|
||||
headers:
|
||||
token: "{{ api_token }}"
|
||||
http_agent: nfc-phpipam-scan-agent/0.2.0-a2
|
||||
http_agent: nfc-phpipam-scan-agent/0.4.0
|
||||
return_content: true
|
||||
status_code:
|
||||
- 200
|
||||
|
@ -1,12 +1,5 @@
|
||||
---
|
||||
|
||||
- name: Scan subnet - {{ subnet.address }}
|
||||
ansible.builtin.command:
|
||||
cmd: nmap -sn "{{ subnet.address }}" -oX -
|
||||
become: true
|
||||
register: nmap_scan
|
||||
|
||||
|
||||
- name: Get subnets Address'
|
||||
ansible.builtin.include_tasks:
|
||||
file: tasks/api_call.yaml
|
||||
@ -17,15 +10,72 @@
|
||||
api_query_string: "filter_by=subnetId&filter_value={{ subnet.id }}"
|
||||
|
||||
|
||||
- name: Load Subnet - {{ subnet.address }}
|
||||
- name: Register Subnet API Call
|
||||
ansible.builtin.set_fact:
|
||||
cached_subnet: "{{ lookup('file', cache_filepath) }}"
|
||||
cacheable: false
|
||||
subnet_api_call: "{{ api_call }}"
|
||||
subnet_cache_filepath: "{{ cache_filepath }}"
|
||||
api_call: ''
|
||||
|
||||
|
||||
- name: Get subnet Name Servers
|
||||
ansible.builtin.include_tasks:
|
||||
file: tasks/api_call.yaml
|
||||
vars:
|
||||
api_client_name: "{{ nofusscomputing_phpipam_scan_agent.client_name }}"
|
||||
api_token: "{{ nofusscomputing_phpipam_scan_agent.client_token }}"
|
||||
api_path: "{{ api_nameservers }}"
|
||||
api_query_string: "filter_by=id&filter_value={{ subnet.nameserverId }}"
|
||||
when: >
|
||||
subnet.nameserverId is defined
|
||||
and
|
||||
subnet.resolveDNS | int == 1
|
||||
|
||||
|
||||
- name: Load Nameservers - {{ subnet.address }}
|
||||
ansible.builtin.set_fact:
|
||||
subnet_name_servers: "{{ lookup('file', cache_filepath) }}"
|
||||
cacheable: false
|
||||
no_log: true
|
||||
when: >
|
||||
subnet.nameserverId is defined
|
||||
and
|
||||
subnet.resolveDNS | int == 1
|
||||
and
|
||||
api_call.status | default(0) | int != 404
|
||||
|
||||
|
||||
- name: Scan subnet - {{ subnet.address }}
|
||||
ansible.builtin.command:
|
||||
cmd: >
|
||||
nmap -sn "{{ subnet.address }}" {% if
|
||||
subnet_name_servers is defined
|
||||
and
|
||||
subnet.resolveDNS | int == 1
|
||||
-%}
|
||||
--dns-servers {% for nameserver in subnet_name_servers -%}
|
||||
{% for name_server in nameserver.namesrv1 | split(';') %}
|
||||
{{ name_server }},
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
{%- elif subnet.resolveDNS | int == 1 -%}
|
||||
--system-dns
|
||||
{%- else -%}
|
||||
-n
|
||||
{%- endif %} -oX -
|
||||
become: true
|
||||
register: nmap_scan
|
||||
|
||||
|
||||
- name: Load Subnet - {{ subnet.address }}
|
||||
ansible.builtin.set_fact:
|
||||
cached_subnet: "{{ lookup('file', subnet_cache_filepath) }}"
|
||||
cacheable: false
|
||||
no_log: true
|
||||
when: >
|
||||
subnet_api_call.status | default(0) | int != 404
|
||||
|
||||
|
||||
- name: Process Scan Results - {{ subnet.address }}
|
||||
ansible.builtin.set_fact:
|
||||
subnet_scan_results: |-
|
||||
@ -114,7 +164,7 @@
|
||||
ansible.builtin.uri:
|
||||
headers:
|
||||
Authorization: "Bearer {{ nofusscomputing_phpipam_scan_agent.auth_token | default('no-token-set') }}"
|
||||
http_agent: nfc-phpipam-scan-agent/0.2.0-a2
|
||||
http_agent: nfc-phpipam-scan-agent/0.4.0
|
||||
url: "{{
|
||||
nofusscomputing_phpipam_scan_agent.http_server | default(nfc_c_http_server)
|
||||
}}:{{ nofusscomputing_phpipam_scan_agent.http_port | default(nfc_c_http_port) }}/"
|
||||
|
@ -1,5 +1,41 @@
|
||||
---
|
||||
|
||||
- name: Convert Scan Time to Local Time
|
||||
ansible.builtin.set_fact:
|
||||
scan_time: |-
|
||||
{%- if inbound_data.scan.tz != ('%z' | strftime | string) -%}
|
||||
|
||||
{%- set adjust_time = scan_address.ipaddress.lastSeen -%}
|
||||
|
||||
{%- if ('%z' | strftime)[0:1] == '+' -%}
|
||||
|
||||
{{
|
||||
'%Y-%m-%d %H:%M:%S' | strftime(
|
||||
(adjust_time | to_datetime).strftime('%s') | int -
|
||||
(
|
||||
(inbound_data.scan.tz[1:3] | int * 3600) + (inbound_data.scan.tz[3:5] | int * 60)
|
||||
) | int
|
||||
)
|
||||
}}
|
||||
|
||||
{%- else -%}
|
||||
|
||||
{{
|
||||
'%Y-%m-%d %H:%M:%S' | strftime((adjust_time | to_datetime).strftime('%s') | int +
|
||||
(
|
||||
(inbound_data.scan.tz[1:3] | int * 3600) + (inbound_data.scan.tz[3:5] | int * 60)
|
||||
) | int)
|
||||
}}
|
||||
|
||||
{%- endif -%}
|
||||
|
||||
{%- else -%}
|
||||
|
||||
{{ scan_address.ipaddress.lastSeen }}
|
||||
|
||||
{%- endif %}
|
||||
cacheable: false
|
||||
|
||||
|
||||
- name: "Update IP Address' found - {{ scan_address.ipaddress.ip }}"
|
||||
community.mysql.mysql_query:
|
||||
@ -16,7 +52,7 @@
|
||||
|
||||
UPDATE ipaddresses
|
||||
SET
|
||||
lastSeen = '{{ scan_address.ipaddress.lastSeen }}'
|
||||
lastSeen = '{{ scan_time }}'
|
||||
|
||||
{% if scan_address.ipaddress.hostname | default('') != '' %},
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
UPDATE
|
||||
subnets
|
||||
SET
|
||||
lastDiscovery = '{{ inbound_data.scan.results[0].lastSeen }}'
|
||||
lastDiscovery = '{{ ('%Y-%m-%d %H:%M:%S' | strftime) }}'
|
||||
WHERE
|
||||
subnet = '{{ (inbound_data.scan.subnet | split('/'))[0] | ip2ipam }}'
|
||||
single_transaction: true
|
||||
|
@ -23,7 +23,9 @@
|
||||
ansible.builtin.set_fact:
|
||||
nfc_c_scan_agent_subnets: "{{ nfc_c_scan_agent_subnets + [{
|
||||
'id': network.id,
|
||||
'address': network.subnet + '/' + network.mask
|
||||
'address': network.subnet + '/' + network.mask,
|
||||
'nameserverId': network.nameserverId,
|
||||
'resolveDNS': network.resolveDNS
|
||||
}] }}"
|
||||
loop: "{{ lookup('file', cache_filepath) | default ([]) }}"
|
||||
loop_control:
|
||||
|
Reference in New Issue
Block a user