Ansible Ad-hoc-opdrachtgids met voorbeelden

Ad-hoc-opdrachten worden in Ansible gebruikt om taken direct uit te voeren, en u hoeft ze niet op te slaan voor later gebruik. Dit artikel gaat over Ansible Ad-hoc Command.

Er zijn meerdere taken in Ansible waar je geen apart Ansible-playbook voor hoeft te schrijven; je kunt gewoon een ansible ad-hoc-opdracht uitvoeren voor die taak. Dit zijn eenregelige opdrachten om een ​​enkele taak op de doelhost uit te voeren. Deze commando’s zijn aanwezig in /usr/bin/ansible

Taken zoals het pingen van alle hosts om te controleren of ze actief zijn, het kopiëren van een bestand, het opnieuw opstarten van servers en het installeren van een pakket kunnen eenvoudig worden gedaan via Ansible Ad-hoc Commands. Hier is een lijst met fundamentele Ansible Ad-hoc-opdrachten die u moet kennen.

Basisopdrachten

De onderstaande ad-hocopdracht voert een ping-module uit op alle hosts in het inventarisbestand. Hier is -m de optie voor een module.

<strong>[email protected]:/home/epcdream.nl# ansible all -m ping</strong>
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

Het onderstaande commando voert de setup-module uit op een groep hosts – Client aanwezig in het inventarisbestand ‘/etc/ansible/hosts’.

[email protected]:/home/epcdream.nl# ansible Client -m setup -a "filter=ansible_distribution*"
node1 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "Ubuntu", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/os-release", 
        "ansible_distribution_file_variety": "Debian", 
        "ansible_distribution_major_version": "18", 
        "ansible_distribution_release": "cosmic", 
        "ansible_distribution_version": "18.10", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}

De onderstaande opdracht wordt gebruikt om SSH-wachtwoordverificatie te vragen. U moet de optie –ask-pass toevoegen aan het einde van de opdracht. Nadat de opdracht is uitgevoerd, wordt u gevraagd het SSH-wachtwoord in te voeren.

[email protected]:/home/epcdream.nl# ansible Client -m ping --ask-pass
SSH password: 
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

De onderstaande opdracht geeft u de mogelijkheid om ad-hocopdrachten uit te voeren als een niet-rootgebruiker met rootrechten. De optie –becom geeft de root privileges en -K optie vraagt ​​om het wachtwoord.

[email protected]:/home/epcdream.nl# ansible Client -m shell -a 'fdisk -l' -u epcdream.nl --become -K
BECOME password: 
node1 | CHANGED | rc=0 >>
Disk /dev/loop0: 14.5 MiB, 15208448 bytes, 29704 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop2: 42.1 MiB, 44183552 bytes, 86296 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop3: 149.9 MiB, 157184000 bytes, 307000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop5: 140.7 MiB, 147501056 bytes, 288088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop6: 151.2 MiB, 158584832 bytes, 309736 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop7: 14.8 MiB, 15458304 bytes, 30192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/sda: 500 GiB, 536870912000 bytes, 1048576000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xcef957f5

Device     Boot     Start        End   Sectors   Size Id Type
/dev/sda1            2048  462639103 462637056 220.6G 83 Linux
/dev/sda2  *    462639104  464592895   1953792   954M 83 Linux
/dev/sda3       464592896  482168831  17575936   8.4G 82 Linux swap / Solaris
/dev/sda4       482168832 1048573951 566405120 270.1G 83 Linux


Disk /dev/loop8: 4 MiB, 4218880 bytes, 8240 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Deze ad-hocopdracht wordt gebruikt om het systeem opnieuw op te starten met de optie -f om het aantal vorken te definiëren.

[email protected]:/home/epcdream.nl# ansible Client -a "/sbin/reboot" -f 1

Bestandsoverdracht

De andere ad-hocopdracht hieronder wordt gebruikt om een ​​bestand van een bron naar een bestemming te kopiëren voor een groep hosts (Client) die in het inventarisbestand is gedefinieerd. Nadat u het wachtwoord hebt ingevoerd, is de uitvoer met de parameter “wijzigen” “waar”, wat betekent dat het bestand naar de bestemming is gekopieerd.

[email protected]:/home/epcdream.nl# ansible Client -m copy -a 'src=/home/epcdream.nl/nginx.yml dest=/home/epcdream.nl/Desktop/ owner=root mode=0644' -u root --become -K
BECOME password: 
node1 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "5631822866afd5f19b928edb3ba018385df22dd3", 
    "dest": "/home/epcdream.nl/Desktop/nginx.yml", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634", 
    "mode": "0644", 
    "owner": "root", 
    "size": 280, 
    "src": "/root/.ansible/tmp/ansible-tmp-1562253463.3-214622150088155/source", 
    "state": "file", 
    "uid": 0
}

Voer de onderstaande opdracht uit om te controleren of de kopieermodule correct werkte of niet. Het gekopieerde bestand moet op de bestemming komen die in de vorige opdracht is genoemd.

[email protected]:/home/epcdream.nl# ls Desktop/

nginx.yml

Ik maak een nieuwe map om fetch-module n volgende ad-hocopdracht uit te voeren.

[email protected]:/home/epcdream.nl# mkdir example

[email protected]:/home/epcdream.nl# ls

Desktop  Documents  example  examples.desktop  nginx_new.yml  nginx.yml

De andere ad-hocopdracht hieronder wordt gebruikt om een ​​bestand te downloaden van een host die in de opdracht is gedefinieerd. In deze opdracht downloaden we een bestand met behulp van de fetch-module van de node1-server naar een lokale bestemming op een ansible-knooppunt.

[email protected]:/home/epcdream.nl# ansible node1 -m fetch -a 'src=/etc/sudoers.d/nginx.yml dest=/home/epcdream.nl/example/ flat=yes'

node1 | SUCCESS => {

    "changed": false,

    "checksum": "5631822866afd5f19b928edb3ba018385df22dd3",

    "dest": "/home/epcdream.nl/example/nginx.yml",

    "file": "/etc/sudoers.d/nginx.yml",

    "md5sum": "0d6ffe1069fc25ad4f8ad700277c4634"

}

Controleer of het bestand is gedownload of niet op de bestemming die in de opdracht wordt vermeld.

[email protected]:/home/epcdream.nl# ls example

nginx.yml

Pakketten beheren

De onderstaande opdracht installeert nginx op een groep hosts (Client) die wordt genoemd met behulp van een apt-module.

[email protected]:/home/epcdream.nl# ansible Client -m apt -a 'name=nginx state=latest' --become

node1 | SUCCESS => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "cache_update_time": 1562411227,

    "cache_updated": false,

    "changed": false

}

De onderstaande opdracht verwijdert nginx op een groep hosts (Client) met behulp van de apt-module en verwijdert alle gerelateerde configuraties.

[email protected]:/home/epcdream.nl# ansible Client -m apt -a 'name=nginx state=absent purge=yes' --become

node1 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "stderr": "",

    "stderr_lines": [],

    "stdout": "Reading package lists...nBuilding dependency tree...nReading state information...nThe following packages were automatically installed and are no longer required:n  libnginx-mod-http-geoip libnginx-mod-http-image-filtern  libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-streamn  nginx-common nginx-corenUse 'sudo apt autoremove' to remove them.nThe following packages will be REMOVED:n  nginx*n0 upgraded, 0 newly installed, 1 to remove and 241 not upgraded.nAfter this operation, 44.0 kB disk space will be freed.n(Reading database ... r(Reading database ... 5%r(Reading database ... 10%r(Reading database ... 15%r(Reading database ... 20%r(Reading database ... 25%r(Reading database ... 30%r(Reading database ... 35%r(Reading database ... 40%r(Reading database ... 45%r(Reading database ... 50%r(Reading database ... 55%r(Reading database ... 60%r(Reading database ... 65%r(Reading database ... 70%r(Reading database ... 75%r(Reading database ... 80%r(Reading database ... 85%r(Reading database ... 90%r(Reading database ... 95%r(Reading database ... 100%r(Reading database ... 180191 files and directories currently installed.)rnRemoving nginx (1.15.5-0ubuntu2.1) ...rn",

    "stdout_lines": [

        "Reading package lists...",

        "Building dependency tree...",

        "Reading state information...",

        "The following packages were automatically installed and are no longer required:",

        "  libnginx-mod-http-geoip libnginx-mod-http-image-filter",

        "  libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream",

        "  nginx-common nginx-core",

        "Use 'sudo apt autoremove' to remove them.",

        "The following packages will be REMOVED:",

        "  nginx*",

        "0 upgraded, 0 newly installed, 1 to remove and 241 not upgraded.",

        "After this operation, 44.0 kB disk space will be freed.",

        "(Reading database ... ",

        "(Reading database ... 5%",

        "(Reading database ... 10%",

        "(Reading database ... 15%",

        "(Reading database ... 20%",

        "(Reading database ... 25%",

        "(Reading database ... 30%",

        "(Reading database ... 35%",

        "(Reading database ... 40%",

        "(Reading database ... 45%",

        "(Reading database ... 50%",

        "(Reading database ... 55%",

        "(Reading database ... 60%",

        "(Reading database ... 65%",

        "(Reading database ... 70%",

        "(Reading database ... 75%",

        "(Reading database ... 80%",

        "(Reading database ... 85%",

        "(Reading database ... 90%",

        "(Reading database ... 95%",

        "(Reading database ... 100%",

        "(Reading database ... 180191 files and directories currently installed.)",

        "Removing nginx (1.15.5-0ubuntu2.1) ..."

    ]

}

Services beheren

De ansible ad-hoc-opdracht hieronder voert de servicemodule uit om nginx op de host te starten. De statuswaarde moet worden gestart.

[email protected]:/home/epcdream.nl# ansible Client -m service -a 'name=nginx state=started enabled=yes' --become

node1 | SUCCESS => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": false,

    "enabled": true,

    "name": "nginx",

    "state": "started",

    "status": {

        "ActiveEnterTimestamp": "Sat 2019-07-06 08:28:02 EDT",

        "ActiveEnterTimestampMonotonic": "31411371",

        "ActiveExitTimestampMonotonic": "0",

        "ActiveState": "active",

        "After": "sysinit.target system.slice systemd-journald.socket basic.target network.target",

        "AllowIsolate": "no",

        "AmbientCapabilities": "",

        "AssertResult": "yes",

        "AssertTimestamp": "Sat 2019-07-06 08:27:59 EDT",

        "AssertTimestampMonotonic": "27694868",

        "Before": "multi-user.target shutdown.target",

        "BlockIOAccounting": "no",

        "BlockIOWeight": "[not set]",

        "CapabilityBoundingSet": "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm cap_block_suspend",

        "CollectMode": "inactive",

        "ConditionResult": "yes",

        "ConditionTimestamp": "Sat 2019-07-06 08:27:59 EDT",

        "ConditionTimestampMonotonic": "27694867",

        "ConfigurationDirectoryMode": "0755",

        "Conflicts": "shutdown.target",

        "ControlGroup": "/system.slice/nginx.service",

        "ControlPID": "0",

        "ExecMainStartTimestamp": "Sat 2019-07-06 08:28:02 EDT",

        "ExecMainStartTimestampMonotonic": "31411353",

        "ExecMainStatus": "0",

        "ExecReload": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -g daemon on; master_process on; -s reload ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

        "ExecStart": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -g daemon on; master_process on; ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

        "ExecStartPre": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -t -q -g daemon on; master_process on; ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

        "ExecStop": "{ path=/sbin/start-stop-daemon ; argv[]=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid ; ignore_errors=yes ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

        "FailureAction": "none",

        "FileDescriptorStoreMax": "0",

        "FragmentPath": "/lib/systemd/system/nginx.service",

        "GID": "[not set]",

        "GuessMainPID": "yes",

        "IOAccounting": "no",

        "IOSchedulingClass": "0",

        "IOSchedulingPriority": "0",

        "IOWeight": "[not set]",

    }

}

Het onderstaande voert de servicemodule uit om nginx op de host te stoppen. De statuswaarde verandert in gestopt.

[email protected]:/home/epcdream.nl# ansible Client -m service -a 'name=nginx state=stopped' --become

node1 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "name": "nginx",

    "state": "stopped",

    "status": {

        "ActiveEnterTimestamp": "Sat 2019-07-06 08:28:02 EDT",

        "ActiveEnterTimestampMonotonic": "31411371",

        "ActiveExitTimestampMonotonic": "0",

        "ActiveState": "active",

        "After": "sysinit.target system.slice systemd-journald.socket basic.target network.target",

        "AllowIsolate": "no",

        "AmbientCapabilities": "",

        "AssertResult": "yes",

        "AssertTimestamp": "Sat 2019-07-06 08:27:59 EDT",

        "AssertTimestampMonotonic": "27694868",

        "Before": "multi-user.target shutdown.target",

        "BlockIOAccounting": "no",

        "BlockIOWeight": "[not set]",

        "CPUAccounting": "no",

        "CPUQuotaPerSecUSec": "infinity",

        "CanReload": "yes",

        "CanStart": "yes",

        "CanStop": "yes",

        "CapabilityBoundingSet": "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm cap_block_suspend",

        "CollectMode": "inactive",

        "ConditionResult": "yes",

        "ConditionTimestamp": "Sat 2019-07-06 08:27:59 EDT",

        "ConditionTimestampMonotonic": "27694867",

        "ConfigurationDirectoryMode": "0755",

        "Conflicts": "shutdown.target",

        "ControlGroup": "/system.slice/nginx.service",

        "ControlPID": "0",

        "DefaultDependencies": "yes",

        "Delegate": "no",

        "Description": "A high performance web server and a reverse proxy server",

        "DevicePolicy": "auto",

        "Documentation": "man:nginx(8)",

        "DynamicUser": "no",

  }

}

Het systeem controleren

De hieronder vermelde ansible ad-hoc-opdracht voert een shell-module uit om de beschikbare schijf op rootpartities te controleren.

[email protected]:/home/epcdream.nl# ansible Client -m shell -a 'df -h /dev/sda2' --become

node1 | CHANGED | rc=0 >>

Filesystem      Size  Used Avail Use% Mounted on

/dev/sda2       923M  113M  748M  14% /boot

Deze opdracht die hieronder wordt vermeld, voert een shell-module uit om het vrije geheugen (RAM) op de host te controleren.

[email protected]:/home/epcdream.nl# ansible Client -m shell -a 'free -m' --become

node1 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache   available

Mem:           5101         854        2760          27        1487        3947

Swap:          8581           0        8581

Deze opdracht controleert de uptime van elke draaiende server.

[email protected]:/home/epcdream.nl# ansible Client -a "uptime"

node1 | CHANGED | rc=0 >>

 11:31:17 up 1 day,  2:40,  2 users,  load average: 0.23, 0.05, 0.02

Feiten verzamelen

De andere ad-hocopdracht hieronder geeft u alle ad-hocinformatie van uw systeem, inclusief alle variabelen die in het systeem aanwezig zijn.

[email protected]:/home/epcdream.nl# ansible all -m setup

node1 | SUCCESS => {

    "ansible_facts": {

        "ansible_all_ipv4_addresses": [

            "172.17.0.1",

            "10.0.2.15"

        ],

        "ansible_all_ipv6_addresses": [

            "fe80::763e:c0b4:14df:b273"

        ],

        "ansible_apparmor": {

            "status": "enabled"

        },

        "ansible_architecture": "x86_64",

        "ansible_bios_date": "12/01/2006",

        "ansible_bios_version": "VirtualBox",

        "ansible_cmdline": {

            "BOOT_IMAGE": "/vmlinuz-4.18.0-25-generic",

            "quiet": true,

            "ro": true,

            "root": "UUID=5f85d8b7-0ab2-48c9-9e6e-4ecfbcbdaa83",

            "splash": true

        },

        "ansible_date_time": {

            "date": "2019-07-07",

            "day": "07",

            "epoch": "1562525628",

            "hour": "14",

            "iso8601": "2019-07-07T18:53:48Z",

            "iso8601_basic": "20190707T145348850596",

            "iso8601_basic_short": "20190707T145348",

            "iso8601_micro": "2019-07-07T18:53:48.850697Z",

            "minute": "53",

            "month": "07",

            "second": "48",

            "time": "14:53:48",

            "tz": "EDT",

            "tz_offset": "-0400",

            "weekday": "Sunday",

            "weekday_number": "0",

            "weeknumber": "26",

            "year": "2019"

        },

        "ansible_default_ipv4": {

            "address": "10.0.2.15",

            "alias": "enp0s3",

            "broadcast": "10.0.2.255",

            "gateway": "10.0.2.2",

            "interface": "enp0s3",

            "macaddress": "08:00:27:68:64:9a",

            "mtu": 1500,

            "netmask": "255.255.255.0",

            "network": "10.0.2.0",

            "type": "ether"

        },

        "ansible_default_ipv6": {},

        "ansible_device_links": {

            "ids": {

                "sda": [

                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5"

                ],

                "sda1": [

                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part1"

                ],

                "sda2": [

                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part2"

                ],

                "sda3": [

                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part3"

                ],

                "sda4": [

                    "ata-VBOX_HARDDISK_VB3a0a2351-0b6c0ed5-part4"

                ],

                "sr0": [

                    "ata-VBOX_CD-ROM_VB2-01700376"

                ]

            },

            "labels": {

                "sr0": [

                    "VBox_GAs_6.0.2"

                ]

            },

            "masters": {},

            "uuids": {

                "sda1": [

                    "5f85d8b7-0ab2-48c9-9e6e-4ecfbcbdaa83"

                ],

                "sda2": [

                    "b8b7f87b-c3bf-48ed-a44c-f9b3ce0afbe5"

                ],

                "sda3": [

                    "a6c77fa6-e292-4a0d-b21f-8804f1949bbd"

                ],

                "sda4": [

                    "8207f970-4d9a-47db-a5d5-f620e5b17b7b"

                ],

                "sr0": [

                    "2019-01-14-14-57-19-65"

                ]

            }

        },

        "ansible_devices": {

            "loop0": {

                "holders": [],

                "host": "",

                "links": {

                    "ids": [],

                    "labels": [],

                    "masters": [],

                    "uuids": []

                },

                "model": null,

                "partitions": {},

                "removable": "0",

                "rotational": "1",

                "sas_address": null,

                "sas_device_handle": null,

                "scheduler_mode": "none",

                "sectors": "29704",

                "sectorsize": "512",

                "size": "14.50 MB",

                "support_discard": "4096",

                "vendor": null,

                "virtual": 1

            },

            "loop1": {

                "holders": [],

                "host": "",

                "links": {

                    "ids": [],

                    "labels": [],

                    "masters": [],

                    "uuids": []

                },

                "model": null,

                "partitions": {},

                "removable": "0",

                "rotational": "1",

                "sas_address": null,

                "sas_device_handle": null,

                "scheduler_mode": "none",

                "sectors": "0",

                "sectorsize": "512",

                "size": "0.00 Bytes",

                "support_discard": "4096",

                "vendor": null,

                "virtual": 1

            },

}

Dus dat ging allemaal over Ansible Ad-hoc Commando’s. Ga je gang en probeer deze commando’s op je ansible-setup. Gebruik deze opdrachten om ansible-modules uit te voeren zonder een Ansible-playbook te schrijven om die taken uit te voeren. Laat een opmerking achter als u problemen ondervindt bij het uitvoeren van deze opdrachten.

  8 E-halsbanden om uw honden te trainen

gerelateerde berichten