├── .editorconfig ├── .git-blame-ignore-revs ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── docs.yml │ └── test.yml ├── .gitignore ├── .typos.toml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── MANIFEST.in ├── README.md ├── codecov.yml ├── docs ├── __init__.py ├── api │ ├── connectors.md │ ├── deploys.md │ ├── facts.md │ ├── index.rst │ ├── operations.md │ └── reference.rst ├── arguments.rst ├── changes.rst ├── cli.md ├── compatibility.md ├── conf.py ├── connectors.rst ├── contributing.md ├── deploy-process.rst ├── examples.rst ├── examples │ ├── client_side_assets.md │ ├── data_multiple_environments.md │ ├── dynamic_execution_deploy.md │ ├── dynamic_inventories_data.md │ ├── groups_roles.md │ └── secret_storage.md ├── facts.rst ├── faq.rst ├── getting-started.rst ├── index.rst ├── install.md ├── inventory-data.rst ├── operations.rst ├── performance.rst ├── static │ ├── logo_small.png │ └── performance.png ├── support.md ├── using-operations.rst └── utils.py ├── examples └── README.md ├── pyinfra ├── __init__.py ├── __main__.py ├── api │ ├── __init__.py │ ├── arguments.py │ ├── arguments_typed.py │ ├── command.py │ ├── config.py │ ├── connect.py │ ├── connectors.py │ ├── deploy.py │ ├── exceptions.py │ ├── facts.py │ ├── host.py │ ├── inventory.py │ ├── operation.py │ ├── operations.py │ ├── state.py │ └── util.py ├── connectors │ ├── __init__.py │ ├── base.py │ ├── chroot.py │ ├── docker.py │ ├── dockerssh.py │ ├── local.py │ ├── ssh.py │ ├── ssh_util.py │ ├── sshuserclient │ │ ├── __init__.py │ │ ├── client.py │ │ └── config.py │ ├── terraform.py │ ├── util.py │ └── vagrant.py ├── context.py ├── facts │ ├── __init__.py │ ├── apk.py │ ├── apt.py │ ├── brew.py │ ├── bsdinit.py │ ├── cargo.py │ ├── choco.py │ ├── crontab.py │ ├── deb.py │ ├── dnf.py │ ├── docker.py │ ├── efibootmgr.py │ ├── files.py │ ├── flatpak.py │ ├── freebsd.py │ ├── gem.py │ ├── git.py │ ├── gpg.py │ ├── hardware.py │ ├── iptables.py │ ├── launchd.py │ ├── lxd.py │ ├── mysql.py │ ├── npm.py │ ├── openrc.py │ ├── opkg.py │ ├── pacman.py │ ├── pip.py │ ├── pipx.py │ ├── pkg.py │ ├── pkgin.py │ ├── podman.py │ ├── postgres.py │ ├── postgresql.py │ ├── rpm.py │ ├── runit.py │ ├── selinux.py │ ├── server.py │ ├── snap.py │ ├── systemd.py │ ├── sysvinit.py │ ├── upstart.py │ ├── util │ │ ├── __init__.py │ │ ├── databases.py │ │ ├── packaging.py │ │ ├── units.py │ │ └── win_files.py │ ├── vzctl.py │ ├── xbps.py │ ├── yum.py │ ├── zfs.py │ └── zypper.py ├── local.py ├── operations │ ├── __init__.py │ ├── apk.py │ ├── apt.py │ ├── brew.py │ ├── bsdinit.py │ ├── cargo.py │ ├── choco.py │ ├── crontab.py │ ├── dnf.py │ ├── docker.py │ ├── files.py │ ├── flatpak.py │ ├── freebsd │ │ ├── __init__.py │ │ ├── freebsd_update.py │ │ ├── pkg.py │ │ ├── service.py │ │ └── sysrc.py │ ├── gem.py │ ├── git.py │ ├── iptables.py │ ├── launchd.py │ ├── lxd.py │ ├── mysql.py │ ├── npm.py │ ├── openrc.py │ ├── opkg.py │ ├── pacman.py │ ├── pip.py │ ├── pipx.py │ ├── pkg.py │ ├── pkgin.py │ ├── postgres.py │ ├── postgresql.py │ ├── puppet.py │ ├── python.py │ ├── runit.py │ ├── selinux.py │ ├── server.py │ ├── snap.py │ ├── ssh.py │ ├── systemd.py │ ├── sysvinit.py │ ├── upstart.py │ ├── util │ │ ├── __init__.py │ │ ├── docker.py │ │ ├── files.py │ │ ├── packaging.py │ │ └── service.py │ ├── vzctl.py │ ├── xbps.py │ ├── yum.py │ ├── zfs.py │ └── zypper.py ├── progress.py ├── py.typed └── version.py ├── pyinfra_cli ├── __init__.py ├── __main__.py ├── commands.py ├── exceptions.py ├── inventory.py ├── log.py ├── main.py ├── prints.py ├── util.py └── virtualenv.py ├── pyproject.toml ├── scripts ├── build-public-docs.sh ├── cleanup_words.py ├── dev-lint.sh ├── dev-test-e2e.sh ├── dev-test.sh ├── generate_api_docs.py ├── generate_arguments_doc.py ├── generate_connectors_docs.py ├── generate_facts_docs.py ├── generate_operations_docs.py ├── generate_redirect_pages.py ├── make_github_release.py ├── pyinfra-complete.sh ├── pyinfra-complete.zsh ├── release.sh └── spellcheck.sh ├── setup.cfg ├── setup.py └── tests ├── __init__.py ├── end-to-end ├── conftest.py ├── test_e2e_docker.py ├── test_e2e_local.py └── test_e2e_ssh.py ├── facts ├── apk.ApkPackages │ ├── packages.json │ └── packages_2.json ├── apt.AptKeys │ └── keys.json ├── apt.AptSources │ ├── component_with_number.json │ └── sources.json ├── apt.SimulateOperationWillChange │ ├── upgrade-nochanges.json │ └── upgrade.json ├── brew.BrewCasks │ └── casks.json ├── brew.BrewPackages │ └── packages.json ├── brew.BrewTaps │ └── taps.json ├── brew.BrewVersion │ ├── bad_output.json │ └── version.json ├── cargo.CargoPackages │ └── packages.json ├── choco.ChocoPackages │ └── packages.json ├── choco.ChocoVersion │ └── version.json ├── crontab.Crontab │ ├── comments.json │ ├── simple.json │ └── simple_user.json ├── deb.DebPackage │ ├── package.json │ └── whitespace.json ├── deb.DebPackages │ ├── hold_packages.json │ └── packages.json ├── dnf.DnfRepositories │ ├── repos-with-spaces.json │ └── repos.json ├── docker.DockerContainer │ └── container.json ├── docker.DockerContainers │ └── container.json ├── docker.DockerImages │ └── images.json ├── efibootmgr.EFIBootMgr │ ├── boot_entries.json │ ├── boot_entries2.json │ ├── boot_entries_complex.json │ └── not_uefi.json ├── files.Block │ ├── defaults.json │ ├── no_markers_found.json │ └── not_found.json ├── files.Directory │ ├── file.json │ ├── link.json │ └── valid.json ├── files.File │ ├── directory.json │ ├── invalid_output.json │ ├── link.json │ ├── mode_setgid_setuid.json │ ├── mode_sticky.json │ ├── tilde.json │ ├── tilde_with_space.json │ ├── valid.json │ ├── valid_needs_quotes.json │ └── valid_with_space.json ├── files.FindDirectories │ └── directories.json ├── files.FindFiles │ ├── files.json │ ├── files_with_name.json │ └── files_with_name_wildcard.json ├── files.FindInFile │ ├── lines.json │ ├── lines_interpolate.json │ ├── lines_no_interpolate.json │ ├── lines_quote.json │ ├── no_file.json │ └── no_matches.json ├── files.FindLinks │ └── links.json ├── files.Flags │ ├── bad_output.json │ ├── no_flags_set.json │ ├── no_output.json │ ├── one_flag_set.json │ ├── too_much_output.json │ └── two_flags_set.json ├── files.Link │ ├── directory.json │ ├── file.json │ ├── valid.json │ └── valid_centos6.json ├── files.Md5File │ ├── file.json │ ├── file_bsd_style.json │ └── file_needs_quotes.json ├── files.Sha1File │ ├── file.json │ ├── file_bsd_style.json │ └── file_needs_quotes.json ├── files.Sha256File │ ├── file.json │ ├── file_bsd_style.json │ └── file_needs_quotes.json ├── files.Sha384File │ ├── file.json │ ├── file_bsd_style.json │ └── file_needs_quotes.json ├── flatpak.FlatpakPackage │ ├── kodi.json │ ├── not_found.json │ └── vlc.json ├── flatpak.FlatpakPackages │ └── packages.json ├── freebsd.PkgPackage │ ├── package-with-jail.json │ └── package.json ├── freebsd.ServiceScript │ ├── found.json │ └── not-found.json ├── freebsd.ServiceStatus │ ├── not-running.json │ └── running.json ├── freebsd.Sysrc │ ├── found.json │ └── not-found.json ├── gem.GemPackages │ └── packages.json ├── git.GitBranch │ └── branch.json ├── git.GitConfig │ ├── global.json │ ├── multi_value.json │ └── repo.json ├── git.GitTag │ └── tag.json ├── git.GitTrackingBranch │ ├── branch.json │ ├── branch_behind.json │ └── no_branch.json ├── gpg.GpgKey │ ├── key_from_file.json │ └── key_from_url.json ├── gpg.GpgKeys │ ├── keys.json │ └── keys_keyring.json ├── gpg.GpgSecretKeys │ ├── keys.json │ └── keys_keyring.json ├── hardware.BlockDevices │ └── devices.json ├── hardware.Cpus │ ├── invalid.json │ └── valid.json ├── hardware.Ipv4Addresses │ └── linux_ip.json ├── hardware.Ipv4Addrs │ └── linux_ip_multiple.json ├── hardware.Ipv6Addresses │ └── linux_ip.json ├── hardware.Ipv6Addrs │ └── linux_ip_multiple.json ├── hardware.Memory │ ├── vmstat_bsd.json │ └── vmstat_linux.json ├── hardware.NetworkDevices │ ├── linux_ifconfig.json │ ├── linux_ifconfig_multiple.json │ ├── linux_ip.json │ ├── linux_ip_multiple_addrs.json │ ├── linux_ip_multiple_ifaces.json │ └── macos_ifconfig.json ├── iptables.Ip6tablesChains │ └── chains.json ├── iptables.Ip6tablesRules │ └── rules.json ├── iptables.IptablesChains │ └── chains.json ├── iptables.IptablesRules │ └── rules.json ├── launchd.LaunchdStatus │ └── services.json ├── lxd.LxdContainers │ └── stripped.json ├── mysql.MysqlDatabases │ ├── multiple.json │ └── multiple_custom_connection.json ├── mysql.MysqlUserGrants │ └── multiple.json ├── mysql.MysqlUsers │ └── multiple.json ├── npm.NpmPackages │ ├── local_packages.json │ └── packages.json ├── openrc.OpenrcEnabled │ ├── services.json │ └── services_runlevel.json ├── openrc.OpenrcStatus │ ├── services.json │ └── services_runlevel.json ├── opkg.OpkgConf │ └── opkg_conf.json ├── opkg.OpkgFeeds │ └── opkg_feeds.json ├── opkg.OpkgInstallableArchitectures │ └── opkg_installable_architectures.json ├── opkg.OpkgPackages │ └── opkg_packages.json ├── opkg.OpkgUpgradeablePackages │ └── opkg_upgradeable_packages.json ├── pacman.PacmanPackages │ └── packages.json ├── pip.Pip3Packages │ └── packages.json ├── pip.PipPackages │ ├── packages.json │ └── packages_pip3.json ├── pipx.PipxEnvironment │ └── environment.json ├── pipx.PipxPackages │ └── packages.json ├── pkg.PkgPackages │ └── packages.json ├── pkgin.PkginPackages │ └── packages.json ├── podman.PodmanPs │ ├── empty.json │ └── onecontainer.json ├── podman.PodmanSystemInfo │ └── info1.json ├── postgresql.PostgresqlDatabases │ └── multiple.json ├── postgresql.PostgresqlRoles │ ├── multiple.json │ └── multiple_custom_connection.json ├── rpm.RpmPackage │ └── package.json ├── rpm.RpmPackageProvides │ └── package.json ├── rpm.RpmPackages │ └── packages.json ├── runit.RunitManaged │ ├── single.json │ └── status.json ├── runit.RunitStatus │ ├── single.json │ └── status.json ├── selinux.FileContext │ └── file_context.json ├── selinux.FileContextMapping │ ├── found.json │ └── not_found.json ├── selinux.SEBoolean │ └── get.json ├── selinux.SEPort │ ├── generic_and_specific.json │ ├── get_bad_port.json │ └── only_generic.json ├── selinux.SEPorts │ ├── line_noise_input.json │ ├── multiple_single_ports.json │ ├── only_single_port.json │ ├── port_range.json │ └── single_and_range.json ├── server.Arch │ └── arch.json ├── server.Command │ └── command.json ├── server.Date │ └── date.json ├── server.Groups │ └── groups.json ├── server.HasGui │ ├── gui_absent.json │ └── gui_present.json ├── server.Home │ ├── home.json │ ├── root.json │ └── some_user.json ├── server.Hostname │ └── hostname.json ├── server.KernelModules │ └── modules.json ├── server.LinuxDistribution │ ├── archlinux.json │ ├── centos-6.json │ ├── centos-7.json │ ├── no_match.json │ └── ubuntu.json ├── server.LinuxGui │ └── gnome_present.json ├── server.LinuxName │ └── ubuntu.json ├── server.Locales ├── server.LsbRelease │ └── release.json ├── server.Mounts │ └── mounts.json ├── server.Os │ └── os.json ├── server.OsVersion │ └── os_version.json ├── server.Port │ ├── empty.json │ ├── one-process.json │ └── two-processes.json ├── server.SecurityLimits │ └── security_limits.json ├── server.Selinux │ ├── no-output.json │ └── selinux.json ├── server.Sysctl │ ├── sysctl_linux.json │ └── sysctl_macos.json ├── server.Users │ └── mixed.json ├── server.Which │ └── which.json ├── snap.SnapPackage │ ├── lxd.json │ ├── not_found.json │ ├── snapd.json │ └── vlc.json ├── snap.SnapPackages │ └── packages.json ├── systemd.SystemdEnabled │ ├── machine_services.json │ ├── root_machine_services.json │ ├── services.json │ ├── user_machine_services.json │ └── user_services.json ├── systemd.SystemdStatus │ ├── machine_services.json │ ├── root_machine_services.json │ ├── services.json │ ├── services_invalid_output.json │ ├── user_machine_services.json │ └── user_services.json ├── sysvinit.InitdStatus │ └── services.json ├── upstart.UpstartStatus │ └── services.json ├── vzctl.OpenvzContainers │ └── containers.json ├── xbps.XbpsPackages │ ├── dot-in-package-name.json │ └── packages.json ├── yum.YumRepositories │ └── repos.json ├── zfs.Datasets │ └── datasets.yaml ├── zfs.Filesystems │ └── filesystems.yaml ├── zfs.Pools │ └── pools.yaml ├── zfs.Snapshots │ └── snapshots.yaml ├── zfs.Volumes │ └── volumes.yaml └── zypper.ZypperRepositories │ └── repos.json ├── operations ├── apk.packages │ ├── add_packages.json │ ├── remove_packages.json │ ├── upgrade_packages.json │ └── upgrade_update.json ├── apk.upgrade │ └── upgrade_available.json ├── apt.deb │ ├── add.json │ ├── add_existing.json │ ├── download_add.json │ ├── remove_existing.json │ └── remove_no_exist.json ├── apt.dist_upgrade │ ├── dist_upgrade.json │ └── dist_upgrade_autoremove.json ├── apt.key │ ├── add.json │ ├── add_exists.json │ ├── add_keyserver.json │ ├── add_keyserver_exists.json │ ├── add_keyserver_multiple.json │ ├── add_keyserver_multiple_partial.json │ ├── add_keyserver_no_keyid.json │ ├── add_no_gpg.json │ └── add_url.json ├── apt.packages │ ├── add_package.json │ ├── add_package_allow_downgrades.json │ ├── add_package_force.json │ ├── add_package_no_recommends.json │ ├── add_packages.json │ ├── install_with_args.json │ ├── remove_packages.json │ ├── remove_packages_with_args.json │ ├── update_cache_old.json │ ├── update_cached.json │ ├── update_nocache.json │ ├── update_upgrade.json │ └── upgrade_packages.json ├── apt.ppa │ ├── add.json │ └── remove.json ├── apt.repo │ ├── add.json │ ├── add_existing.json │ ├── add_filename.json │ └── remove.json ├── apt.upgrade │ ├── upgrade.json │ └── upgrade_autoremove.json ├── brew.cask_upgrade │ ├── new_cli_upgrade.json │ └── old_cli_upgrade.json ├── brew.casks │ ├── add_casks_upgrade.json │ ├── new_cli_add_casks.json │ └── old_cli_add_casks.json ├── brew.packages │ ├── add_packages.json │ ├── remove_packages.json │ ├── upgrade_packages.json │ └── upgrade_update.json ├── brew.tap │ ├── add_exists.json │ ├── add_tap.json │ ├── add_tap_bad_url.json │ ├── add_tap_no_args.json │ ├── add_tap_url.json │ ├── add_tap_url_exists.json │ ├── add_tap_url_no_src.json │ ├── remove_no_exists.json │ └── remove_tap.json ├── brew.upgrade │ └── upgrade.json ├── bsdinit.service │ ├── disabled.json │ ├── enabled.json │ ├── reload.json │ ├── skip_started.json │ ├── start.json │ └── stop.json ├── cargo.packages │ ├── add_packages.json │ └── remove_packages.json ├── choco.install │ └── install.json ├── choco.packages │ ├── add_packages.json │ └── remove_packages.json ├── crontab.crontab │ ├── add.json │ ├── add_another.json │ ├── add_existing.json │ ├── add_existing_int.json │ ├── add_named.json │ ├── add_special_time.json │ ├── add_user.json │ ├── edit.json │ ├── edit_named.json │ ├── edit_special_time.json │ └── remove.json ├── dnf.key │ └── add.json ├── dnf.packages │ ├── add_packages.json │ ├── install_with_args.json │ ├── install_with_nobest.json │ ├── noop_add_package_alias.json │ ├── remove_package.json │ ├── uninstall_with_args.json │ └── update_clean.json ├── dnf.repo │ ├── add.json │ └── remove.json ├── dnf.rpm │ ├── add.json │ ├── add_existing.json │ ├── add_existing_upgrade.json │ ├── add_url.json │ └── remove.json ├── docker.container │ ├── add_and_start_no_existent_container.json │ ├── add_existent_container.json │ ├── add_no_existent_container.json │ ├── remove_container.json │ ├── start_container.json │ └── stop_container.json ├── docker.image │ ├── pull_image.json │ └── remove_image.json ├── docker.network │ ├── add_network.json │ ├── add_network_with_gateway.json │ ├── add_network_with_ip_range.json │ ├── add_network_with_opts.json │ └── remove_network.json ├── docker.volume │ ├── add_volume.json │ ├── add_volume_with_driver.json │ └── add_volume_with_labels.json ├── files.block │ ├── add_existing_block_different_content.json │ ├── add_existing_block_different_content_and_backup.json │ ├── add_existing_block_same_content.json │ ├── add_line_given_but_before_eq_after.json │ ├── add_no_content_provided.json │ ├── add_no_existing_block_and_no_line.json │ ├── add_no_existing_block_line_provided.json │ ├── add_no_existing_block_line_provided_escape_regex.json │ ├── add_no_existing_file.json │ ├── add_no_line_given_but_before_ne_after.json │ ├── remove_but_content_not_none.json │ ├── remove_existing_block.json │ ├── remove_no_existing_block.json │ └── remove_no_file.json ├── files.directory │ ├── add.json │ ├── add_force.json │ ├── add_force_backup_dir.json │ ├── add_force_no_backup.json │ ├── add_with_spaces.json │ ├── delete.json │ ├── edit.json │ ├── edit_with_spaces.json │ ├── ignore_link_type.json │ ├── invalid.json │ └── invalid_type.json ├── files.download │ ├── download.json │ ├── download_cache_time.json │ ├── download_cache_time_needs_refresh.json │ ├── download_directory.json │ ├── download_existing_checksum.json │ ├── download_headers_curl.json │ ├── download_headers_wget.json │ ├── download_insecure_curl.json │ ├── download_insecure_wget.json │ ├── download_needs_quotes.json │ ├── download_no_curl_no_wget.json │ ├── download_proxy_curl.json │ ├── download_proxy_wget.json │ ├── download_wget.json │ ├── download_with_checksums.json │ ├── download_with_checksums_needs_quotes.json │ ├── pathlib_download.json │ └── skip_existing.json ├── files.file │ ├── add.json │ ├── add_force.json │ ├── add_force_backup_dir.json │ ├── add_force_backup_dir_nested.json │ ├── add_force_no_backup.json │ ├── add_special_chars.json │ ├── add_with_spaces.json │ ├── create_directory.json │ ├── delete.json │ ├── delete_with_spaces.json │ ├── edit.json │ ├── edit_nothing.json │ ├── invalid.json │ ├── invalid_type.json │ └── touch.json ├── files.flags │ ├── clear_no_flags.json │ ├── clear_one_flag_already_clear.json │ ├── clear_one_flag_was_set.json │ ├── clear_two_flags.json │ ├── clear_two_flags_already_clear.json │ ├── clear_two_flags_first_already_clear.json │ ├── clear_two_flags_second_already_clear.json │ ├── set_no_flags.json │ ├── set_one_flag_already_set.json │ ├── set_one_flag_not_yet_set.json │ ├── set_two_flags.json │ ├── set_two_flags_already_set.json │ ├── set_two_flags_first_already_set.json │ └── set_two_flags_second_already_set.json ├── files.get │ ├── create_directory.json │ ├── different_remote.json │ ├── no_local.json │ ├── no_remote.json │ ├── path_with_spaces.json │ ├── path_with_spaces_already_escaped.json │ └── pathlib_path_with_spaces.json ├── files.line │ ├── add.json │ ├── add_backup.json │ ├── add_existing.json │ ├── add_replace.json │ ├── add_replace_noop.json │ ├── add_with_quote.json │ ├── edit.json │ ├── edit_backup.json │ └── pathlib_edit.json ├── files.link │ ├── add.json │ ├── add_force.json │ ├── add_force_backup_dir.json │ ├── add_force_no_backup.json │ ├── add_no_target.json │ ├── add_with_spaces.json │ ├── create_directory.json │ ├── delete.json │ ├── edit.json │ ├── edit_nothing.json │ ├── invalid.json │ ├── invalid_type.json │ └── pathlib_edit.json ├── files.move │ ├── directory.json │ ├── invalid_dest.json │ ├── invalid_src.json │ ├── link.json │ ├── no_conflict.json │ ├── no_overwrite.json │ └── overwrite.json ├── files.put │ ├── change_mode_owner.json │ ├── change_mode_owner_with_spaces.json │ ├── copy_local_permissions.json │ ├── create_directory.json │ ├── different_remote.json │ ├── no_change.json │ ├── no_change_same_mode_as_local.json │ ├── no_local.json │ ├── no_remote.json │ ├── path_with_spaces.json │ ├── path_with_spaces_already_escaped.json │ ├── pathlib_with_spaces.json │ └── upload_to_directory.json ├── files.replace │ ├── no_match.json │ ├── replace_double_quotes_interpolate.json │ ├── replace_double_quotes_no_interpolate.json │ ├── replace_single_quotes_interpolate.json │ ├── replace_single_quotes_no_interpolate.json │ ├── simple_interpolate.json │ └── simple_no_interpolate.json ├── files.sync │ ├── sync_delete_posix.json │ ├── sync_delete_windows.json │ ├── sync_destination_link.json │ ├── sync_exclude_multiple.json │ ├── sync_no_destination_exist.json │ ├── sync_no_local_exist_posix.json │ ├── sync_no_local_exist_windows.json │ ├── sync_partial_exists.json │ └── sync_special_chars.json ├── files.template │ ├── invalid_template_syntax.json │ ├── no_remote.json │ └── undefined_template_variable.json ├── flatpak.packages │ ├── install_package.json │ ├── install_packages.json │ └── remove_packages.json ├── freebsd.freebsd_update.update │ └── update.json ├── freebsd.pkg.autoremove │ ├── autoremove-with-jail.json │ └── autoremove.json ├── freebsd.pkg.clean │ ├── clean-all-with-jail.json │ ├── clean-all.json │ ├── clean-with-jail.json │ └── clean.json ├── freebsd.pkg.install │ ├── install-with-custom-repo.json │ ├── install-with-jail-and-custom-repo.json │ ├── install-with-jail.json │ └── install.json ├── freebsd.pkg.remove │ ├── remove-with-jail.json │ └── remove.json ├── freebsd.pkg.update │ └── update.json ├── freebsd.pkg.upgrade │ └── upgrade.json ├── freebsd.service.service │ ├── custom.json │ ├── reload.json │ ├── restart.json │ ├── start.json │ └── stop.json ├── freebsd.sysrc.sysrc │ ├── add.json │ ├── del.json │ ├── set.json │ └── sub.json ├── gem.packages │ ├── add_packages.json │ └── remove_packages.json ├── git.bare_repo │ ├── chmod.json │ ├── delete.json │ └── init.json ├── git.config │ ├── add_existing_multi_value.json │ ├── add_first_multi_value.json │ ├── add_second_multi_value.json │ ├── edit_global.json │ ├── edit_system.json │ ├── set_existing_global.json │ ├── set_existing_system.json │ ├── set_global.json │ ├── set_repo.json │ └── set_system.json ├── git.repo │ ├── branch_pull.json │ ├── clone.json │ ├── clone_keyscan.json │ ├── clone_keyscan_invalid.json │ ├── rebase.json │ ├── recursive_submodules.json │ └── update_submodules.json ├── git.worktree │ ├── create.json │ ├── create_detached.json │ ├── create_detached_from_commitish.json │ ├── create_existing_branch.json │ ├── create_force.json │ ├── create_from_commitish.json │ ├── create_new_branch.json │ ├── create_new_branch_from_commitish.json │ ├── pull.json │ ├── pull_disable.json │ ├── pull_from_bad_remote_branch.json │ ├── pull_from_remote_branch.json │ ├── pull_rebase from_remote_branch.json │ ├── pull_rebase.json │ ├── remove.json │ └── remove_force.json ├── iptables.chain │ ├── add_chain.json │ ├── delete_chain.json │ ├── delete_chain_noop.json │ └── edit_chain.json ├── iptables.rule │ ├── add_log_rule.json │ ├── add_rule.json │ ├── add_to_ports.json │ ├── add_to_source.json │ ├── add_v6_rule.json │ ├── already_absent.json │ ├── already_present.json │ ├── delete_rule.json │ ├── invalid_destination_port.json │ ├── invalid_log_prefix.json │ ├── invalid_source_destination.json │ ├── invalid_to_destination.json │ └── invalid_to_ports.json ├── launchd.service │ ├── restart.json │ ├── restart_stopped.json │ ├── start.json │ ├── start_running.json │ └── stop.json ├── lxd.container │ ├── add_container.json │ ├── already_absent.json │ ├── already_present.json │ ├── delete_container.json │ └── delete_running_container.json ├── mysql.database │ ├── add.json │ ├── add_noop.json │ ├── add_privileges.json │ ├── delete.json │ └── delete_noop.json ├── mysql.dump │ └── dump.json ├── mysql.load │ ├── load.json │ └── load_space.json ├── mysql.privileges │ ├── add.json │ ├── add_all_with_grant_option.json │ ├── add_database.json │ ├── add_delete.json │ ├── add_delete_usage.json │ ├── add_existing.json │ ├── add_table.json │ ├── add_table_invalid.json │ ├── add_with_grant_option.json │ ├── delete.json │ ├── delete_all.json │ ├── delete_all_with_grant_option.json │ ├── delete_with_grant_option.json │ ├── remove_noop.json │ └── remove_usage.json ├── mysql.sql │ ├── execute.json │ └── execute_mysql_kwargs.json ├── mysql.user │ ├── add.json │ ├── add_noop.json │ ├── add_password.json │ ├── add_privileges.json │ ├── add_resources.json │ ├── add_ssl.json │ ├── add_x509.json │ ├── add_x509_specified.json │ ├── delete.json │ ├── invalid_require_cipher.json │ ├── invalid_require_issuer.json │ ├── invalid_require_subject.json │ ├── invalid_require_type.json │ ├── remove_noop.json │ ├── update_resources.json │ ├── update_resources_partial.json │ ├── update_ssl.json │ ├── update_x509.json │ ├── update_x509_specified.json │ └── update_x509_specified_partial.json ├── npm.packages │ ├── add_local_packages.json │ ├── add_packages.json │ └── remove_packages.json ├── openrc.service │ ├── disable.json │ ├── enable.json │ ├── running_noop.json │ ├── start.json │ ├── stop.json │ └── stopped_noop.json ├── opkg.packages │ ├── add_existing_package.json │ ├── add_multiple_packages.json │ ├── add_one_package.json │ ├── add_with_unallowed_pinning.json │ ├── list_of_nulls_package_list.json │ ├── null_package_list.json │ ├── remove_existing_package.json │ ├── remove_existing_package_and_require_update.json │ ├── remove_not_existing_package.json │ └── update_then_add_one.json ├── opkg.update │ └── first_update.json ├── pacman.packages │ ├── add_packages.json │ ├── add_packages_group_expand.json │ ├── remove_packages.json │ ├── remove_packages_expand.json │ └── upgrade_update.json ├── pip.packages │ ├── add_new_virtualenv_packages.json │ ├── add_packages.json │ ├── add_packages_case_insensitive.json │ ├── add_virtualenv_packages.json │ ├── install_extra_args.json │ ├── install_latest_requirements.json │ ├── install_requirements.json │ ├── install_virtualenv_requirements.json │ ├── remove_packages.json │ ├── uninstall_requirements.json │ ├── use_pip3.json │ └── use_pip3_virtualenv.json ├── pip.venv │ └── add_virtualenv.json ├── pip.virtualenv │ ├── add_virtualenv.json │ ├── add_virtualenv_py3.json │ ├── add_with_options.json │ ├── already_absent.json │ ├── already_present.json │ ├── delete_virtualenv.json │ ├── present_empty_directory.json │ ├── use_stdlib_venv.json │ └── use_stdlib_venv_py3.json ├── pipx.ensure_path │ └── ensure_path.json ├── pipx.packages │ ├── add_packages.json │ ├── install_extra_args.json │ └── remove_packages.json ├── pipx.upgrade_all │ └── upgrade_all.json ├── pkg.packages │ ├── pkg_add_packages.json │ ├── pkg_add_packages_with_installurl.json │ ├── pkg_delete_packages.json │ ├── pkg_install_packages.json │ └── pkg_remove_packages.json ├── pkgin.packages │ ├── add_packages.json │ ├── remove_packages.json │ ├── upgrade_packages.json │ └── upgrade_update.json ├── postgresql.database │ ├── add_database.json │ ├── add_database_locales.json │ ├── add_database_owner.json │ ├── remove_database.json │ ├── remove_database_noop.json │ ├── update_database.json │ └── update_database_noop.json ├── postgresql.dump │ └── dump.json ├── postgresql.load │ └── load.json ├── postgresql.role │ ├── role_remove_noop.json │ ├── role_update.json │ ├── role_update_noop.json │ ├── user_add.json │ ├── user_add_no_login.json │ ├── user_add_privileges.json │ ├── user_add_replication.json │ ├── user_add_super.json │ └── user_remove.json ├── postgresql.sql │ └── execute.json ├── puppet.agent │ └── run_agent.json ├── python.call │ └── call_func.json ├── python.raise_exception │ └── call_func.json ├── runit.manage │ ├── manage.json │ └── unmanage.json ├── runit.service │ ├── disable.json │ └── enable.json ├── selinux.boolean │ ├── bad_value.json │ ├── change_not_persistent.json │ ├── change_persistent.json │ └── no_change.json ├── selinux.file_context │ ├── change.json │ └── no_change.json ├── selinux.file_context_mapping │ ├── add_None.json │ ├── add_different.json │ ├── add_no_change.json │ ├── add_none_existeing.json │ ├── delete_existing.json │ └── delete_none_existing.json ├── selinux.port │ ├── add_None.json │ ├── add_different.json │ ├── add_different_direct.json │ ├── add_not_existing.json │ ├── add_not_existing_direct.json │ ├── add_not_existing_protocol.json │ ├── add_same.json │ ├── add_same_direct.json │ ├── remove_existing.json │ ├── remove_existing_direct.json │ ├── remove_not_existing.json │ └── remove_not_existing_direct.json ├── server.group │ ├── add.freebsd.json │ ├── add.json │ ├── delete.freebsd.json │ └── delete.json ├── server.hostname │ ├── hostname_noop.json │ ├── hostnamectl_noop.json │ ├── set_hostname_bsd.json │ ├── set_hostname_linux.json │ └── set_hostnamectl_linux.json ├── server.locale │ ├── add.json │ └── remove.json ├── server.modprobe │ ├── add-list.json │ ├── add.json │ ├── add_exists.json │ ├── add_force.json │ ├── add_multiple_exists.json │ ├── remove-list.json │ └── remove.json ├── server.mount │ ├── mount.json │ ├── mount_device.json │ ├── mount_device_fstype.json │ ├── mount_exists.json │ ├── mount_options.json │ ├── remount_options.json │ └── unmount.json ├── server.packages │ ├── add_apk_packages.json │ ├── add_dnf_packages.json │ └── add_yum_packages.json ├── server.reboot │ └── reboot.json ├── server.script │ └── upload_run.json ├── server.script_template │ └── script.json ├── server.security_limit │ └── set.json ├── server.service │ ├── invalid.json │ ├── start_initd.json │ ├── start_initd_service.json │ ├── start_openrc.json │ ├── start_rcd.json │ ├── start_runit.json │ ├── start_systemd.json │ └── start_upstart.json ├── server.shell │ ├── shell.json │ └── single_shell.json ├── server.sysctl │ ├── set.json │ ├── set_list.json │ ├── set_noop.json │ ├── set_noop_string_value.json │ ├── set_noop_zero_int.json │ └── set_persist.json ├── server.user │ ├── add.json │ ├── add_group_exists.json │ ├── add_home_is_link.json │ ├── add_invalid_home_is_file.json │ ├── add_non_unique.json │ ├── append_secondary_groups.json │ ├── delete.freebsd.json │ ├── delete.json │ ├── edit.json │ ├── key_files.json │ ├── keys.json │ ├── keys_delete.json │ ├── keys_nohome.json │ └── keys_single.json ├── server.wait │ └── port.json ├── snap.package │ ├── install_package.json │ ├── install_package_classic.json │ ├── install_package_with_channel.json │ ├── install_packages.json │ ├── install_refresh_packages.json │ ├── refresh_package.json │ └── remove_packages.json ├── ssh.command │ ├── command.json │ ├── command_quotes.json │ └── command_user_port.json ├── ssh.download │ ├── download.json │ ├── download_exists.json │ ├── download_exists_force.json │ └── download_not_file.json ├── ssh.keyscan │ ├── scan_not_present.json │ ├── scan_present.json │ └── scan_present_force.json ├── ssh.upload │ ├── upload.json │ ├── upload_remote_sudo.json │ └── upload_remote_sudo_user.json ├── systemd.service │ ├── daemon_reload.json │ ├── disabled.json │ ├── enabled.json │ ├── machine_daemon_reload.json │ ├── machine_disabled.json │ ├── machine_enabled.json │ ├── machine_start.json │ ├── running_ambiguous_unit.json │ ├── running_noop.json │ ├── running_timer.json │ ├── start.json │ ├── stopped_noop.json │ ├── timer.json │ ├── user_daemon_reload.json │ ├── user_disabled.json │ ├── user_enabled.json │ ├── user_machine_daemon_reload.json │ ├── user_machine_disabled.json │ ├── user_machine_enabled.json │ ├── user_machine_start.json │ └── user_start.json ├── sysvinit.enable │ └── create.json ├── sysvinit.service │ ├── command.json │ ├── disabled.json │ ├── enabled_chkconfig.json │ ├── enabled_rc-update.json │ ├── enabled_update-rc.d.json │ ├── reload.json │ ├── restart.json │ ├── restart_down.json │ ├── skip_started.json │ ├── start.json │ └── stop.json ├── upstart.service │ ├── disabled.json │ ├── enabled.json │ └── running.json ├── vzctl.create │ ├── add_template.json │ └── already_existing.json ├── vzctl.delete │ └── delete.json ├── vzctl.mount │ └── mount.json ├── vzctl.restart │ ├── restart.json │ └── restart_force.json ├── vzctl.set │ ├── set.json │ ├── set_multiple.json │ └── set_no_save.json ├── vzctl.start │ ├── start.json │ └── start_force.json ├── vzctl.stop │ └── stop.json ├── vzctl.unmount │ └── unmount.json ├── xbps.packages │ ├── add_packages.json │ ├── remove_packages.json │ └── upgrade_update.json ├── yum.key │ └── add.json ├── yum.packages │ ├── add_packages.json │ ├── add_packages_alias.json │ ├── add_packages_alias_different_version.json │ ├── add_packages_alias_multiple_version.json │ ├── install_with_args.json │ ├── install_with_nobest.json │ ├── noop_add_packages_alias.json │ ├── noop_add_packages_alias_multiple_version.json │ ├── remove_package.json │ ├── remove_packages_alias_multiple_version.json │ ├── uninstall_with_args.json │ └── update_clean.json ├── yum.repo │ ├── add.json │ ├── add_url.json │ └── remove.json ├── yum.rpm │ ├── add.json │ ├── add_existing.json │ ├── add_existing_upgrade.json │ ├── add_url.json │ └── remove.json ├── zfs.dataset │ ├── create.yaml │ ├── create_noop.yaml │ ├── create_recursive.yaml │ ├── create_sparse.yaml │ ├── create_volume.yaml │ ├── delete.yaml │ ├── delete_noop.yaml │ ├── delete_recursive.yaml │ └── set_props.yaml ├── zfs.filesystem │ ├── create.yaml │ └── delete.yaml ├── zfs.snapshot │ └── create.yaml ├── zfs.volume │ └── create.yaml ├── zypper.key │ └── add.json ├── zypper.packages │ ├── add_packages.json │ ├── install_with_args.json │ ├── install_with_global_args.json │ ├── uninstall_with_args.json │ ├── uninstall_with_global_args.json │ └── update_clean.json ├── zypper.repo │ ├── add.json │ ├── add_url.json │ └── remove.json └── zypper.rpm │ ├── add.json │ ├── add_existing.json │ ├── add_existing_upgrade.json │ ├── add_url.json │ └── remove.json ├── paramiko_util.py ├── test_api ├── __init__.py ├── test_api.py ├── test_api_arguments.py ├── test_api_command.py ├── test_api_config.py ├── test_api_deploys.py ├── test_api_facts.py ├── test_api_host.py ├── test_api_inventory.py ├── test_api_operations.py └── test_api_util.py ├── test_cli ├── __init__.py ├── deploy │ ├── deploy.py │ ├── deploy_random.py │ ├── files │ │ └── a_file │ ├── group_data │ │ ├── all.py │ │ ├── invalid.json │ │ └── leftover_data.py │ ├── inventories │ │ ├── inventory.py │ │ ├── inventory_all.py │ │ ├── inventory_ansible │ │ ├── inventory_ansible.json │ │ └── inventory_ansible.yml │ ├── tasks │ │ ├── a_task.py │ │ ├── another_task.py │ │ ├── b_task.py │ │ └── nested │ │ │ └── empty_task.py │ ├── templates │ │ └── a_template.j2 │ └── utils.py ├── deploy_fails │ ├── invalid_argument_type.py │ ├── invalid_operation_arg.py │ └── operation_error.py ├── inventories │ └── invalid.py ├── test_cli.py ├── test_cli_deploy.py ├── test_cli_exceptions.py ├── test_cli_inventory.py ├── test_cli_util.py ├── test_context_objects.py ├── user │ └── test_ops.py └── util.py ├── test_connectors ├── __init__.py ├── test_chroot.py ├── test_docker.py ├── test_dockerssh.py ├── test_local.py ├── test_ssh.py ├── test_sshuserclient.py ├── test_terraform.py ├── test_util.py └── test_vagrant.py ├── test_facts.py ├── test_global_arguments.py ├── test_operations.py ├── test_operations_utils.py ├── test_units.py ├── typing ├── invalid │ ├── operation_kwarg.py │ └── operation_kwarg_value.py └── valid │ └── operation.py ├── util.py └── words.txt /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.json] 2 | indent_style = space 3 | indent_size = 4 4 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Run black & isort on everything 2 | 2d4792eba3233c77a298d86e9638434688e3a1c5 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: fizzadar 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | 3 | contact_links: 4 | - name: 📖 Documentation 5 | url: https://docs.pyinfra.com 6 | about: View the pyinfra documentation. 7 | 8 | - name: 💬 Help & Support 9 | url: https://docs.pyinfra.com/page/support.html 10 | about: Please ask and answer usage questions here. 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 💡 Feature Request 4 | about: Suggest an idea for this project. 5 | 6 | --- 7 | 8 | ## Is your feature request related to a problem? Please describe 9 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 10 | 11 | ## Describe the solution you'd like 12 | A clear and concise description of what you want to happen. 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to pyinfra 2 | 3 | 🎉 Hello! Thank you for taking the time to contribute to pyinfra! 🎉 4 | 5 | Please see [**the contributing guide on the pyinfra documentation**](https://docs.pyinfra.com/en/latest/contributing.html). 6 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md LICENSE.md CHANGELOG.md pyinfra/py.typed 2 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | patch: off 4 | project: 5 | default: 6 | threshold: 1% 7 | -------------------------------------------------------------------------------- /docs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/docs/__init__.py -------------------------------------------------------------------------------- /docs/arguments.rst: -------------------------------------------------------------------------------- 1 | Global Arguments 2 | ================ 3 | 4 | In addition to each operations having its own arguments, there are a number of keyword arguments available in all facts, operations and deploys. 5 | 6 | .. note:: 7 | With the exception of ``name`` these are prefixed with ``_`` to avoid clashes with other operation and deploy arguments. 8 | 9 | .. include:: _deploy_globals.rst 10 | -------------------------------------------------------------------------------- /docs/changes.rst: -------------------------------------------------------------------------------- 1 | Changes 2 | ======= 3 | 4 | .. include:: ../CHANGELOG.md 5 | :parser: myst_parser.sphinx_ 6 | -------------------------------------------------------------------------------- /docs/static/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/docs/static/logo_small.png -------------------------------------------------------------------------------- /docs/static/performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/docs/static/performance.png -------------------------------------------------------------------------------- /docs/utils.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def title_line(char, string): 5 | return "".join(char for _ in range(0, len(string))) 6 | 7 | 8 | def format_doc_line(line): 9 | # Bold the : part of each line 10 | line = re.sub(r"\+ ([0-9a-z_\/\*]+)(.*)", r"+ **\1**\2", line) 11 | 12 | # Strip the first 4 characters (first indent from docstring) 13 | return line[4:] 14 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | [Examples have been moved to the **pyinfra-examples** repository](https://github.com/pyinfra-dev/pyinfra-examples). 2 | -------------------------------------------------------------------------------- /pyinfra/__main__.py: -------------------------------------------------------------------------------- 1 | from pyinfra_cli import __main__ # noqa: F401 2 | -------------------------------------------------------------------------------- /pyinfra/connectors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/pyinfra/connectors/__init__.py -------------------------------------------------------------------------------- /pyinfra/connectors/sshuserclient/__init__.py: -------------------------------------------------------------------------------- 1 | from .client import SSHClient # noqa: F401 2 | -------------------------------------------------------------------------------- /pyinfra/facts/__init__.py: -------------------------------------------------------------------------------- 1 | # This file only exists to support: 2 | # from pyinfra import facts 3 | # facts.X.Y 4 | 5 | from glob import glob 6 | from os import path 7 | 8 | module_filenames = glob(path.join(path.dirname(__file__), "*.py")) 9 | module_names = [path.basename(name)[:-3] for name in module_filenames] 10 | __all__ = [name for name in module_names if name != "__init__"] 11 | 12 | from . import * # noqa 13 | -------------------------------------------------------------------------------- /pyinfra/facts/postgresql.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from .postgres import PostgresDatabases, PostgresRoles 4 | 5 | 6 | class PostgresqlRoles(PostgresRoles): 7 | deprecated = True 8 | 9 | 10 | class PostgresqlDatabases(PostgresDatabases): 11 | deprecated = True 12 | -------------------------------------------------------------------------------- /pyinfra/operations/__init__.py: -------------------------------------------------------------------------------- 1 | # This file only exists to support: 2 | # from pyinfra import operations 3 | # operations.X.Y 4 | 5 | from glob import glob 6 | from os import path 7 | 8 | module_filenames = glob(path.join(path.dirname(__file__), "*.py")) 9 | module_names = [path.basename(name)[:-3] for name in module_filenames] 10 | __all__ = [name for name in module_names if name != "__init__"] 11 | 12 | from . import * # noqa 13 | -------------------------------------------------------------------------------- /pyinfra/operations/freebsd/__init__.py: -------------------------------------------------------------------------------- 1 | # This file only exists to support: 2 | # from pyinfra.operations import freebsd 3 | # freebsd.X.Y 4 | 5 | from glob import glob 6 | from os import path 7 | 8 | module_filenames = glob(path.join(path.dirname(__file__), "*.py")) 9 | module_names = [path.basename(name)[:-3] for name in module_filenames] 10 | __all__ = [name for name in module_names if name != "__init__"] 11 | 12 | from . import * # noqa 13 | -------------------------------------------------------------------------------- /pyinfra/operations/util/__init__.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Callable 2 | 3 | if TYPE_CHECKING: 4 | from pyinfra.api.operation import OperationMeta 5 | 6 | 7 | def any_changed(*args: "OperationMeta") -> Callable[[], bool]: 8 | return lambda: any((meta.did_change() for meta in args)) 9 | 10 | 11 | def all_changed(*args: "OperationMeta") -> Callable[[], bool]: 12 | return lambda: all((meta.did_change() for meta in args)) 13 | -------------------------------------------------------------------------------- /pyinfra/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/pyinfra/py.typed -------------------------------------------------------------------------------- /pyinfra/version.py: -------------------------------------------------------------------------------- 1 | try: 2 | try: 3 | from importlib_metadata import version 4 | except ImportError: 5 | from importlib.metadata import version 6 | 7 | __version__ = version("pyinfra") 8 | except Exception: 9 | __version__ = "unknown" 10 | -------------------------------------------------------------------------------- /pyinfra_cli/__init__.py: -------------------------------------------------------------------------------- 1 | # Monkey patch the stdlib for gevent - this _must_ happen here, as early as 2 | # possible, to avoid problems with the stdlib usage elsewhere in pyinfra. API 3 | # scripts should also patch gevent at the start of their execution. 4 | from gevent import monkey # noqa 5 | 6 | monkey.patch_all() # noqa 7 | -------------------------------------------------------------------------------- /scripts/dev-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | echo "Execute black..." 6 | black ./ 7 | 8 | echo "Execute flake8..." 9 | flake8 10 | 11 | echo "Execute mypy..." 12 | mypy 13 | 14 | echo "Linting complete!" 15 | -------------------------------------------------------------------------------- /scripts/dev-test-e2e.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | echo "Execute local end to end tests..." 6 | pytest -m end_to_end_local 7 | 8 | echo "Execute SSH end to end tests..." 9 | pytest -m end_to_end_ssh 10 | 11 | echo "Execute Docker end to end tests..." 12 | pytest -m end_to_end_docker 13 | 14 | echo "Tests complete!" 15 | -------------------------------------------------------------------------------- /scripts/dev-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | echo "Execute pytest..." 6 | pytest $@ 7 | 8 | echo "Tests complete!" 9 | -------------------------------------------------------------------------------- /scripts/spellcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | flake8 --select=SC --ignore= 4 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Import `pyinfra_cli` to trigger gevent monkey patching 2 | import logging # noqa: I100 3 | 4 | import gevent.hub 5 | 6 | import pyinfra_cli # noqa: F401 7 | from pyinfra import logger 8 | 9 | logging.basicConfig(level=logging.DEBUG) 10 | logger.setLevel(logging.DEBUG) 11 | 12 | # Don't print out exceptions inside greenlets (because here we expect them!) 13 | gevent.hub.Hub.NOT_ERROR = (Exception,) 14 | -------------------------------------------------------------------------------- /tests/end-to-end/test_e2e_docker.py: -------------------------------------------------------------------------------- 1 | """ 2 | Docker based integration tests. 3 | """ 4 | 5 | import pytest 6 | 7 | 8 | @pytest.mark.end_to_end 9 | @pytest.mark.end_to_end_docker 10 | def test_int_docker_install_package_ubuntu(helpers): 11 | helpers.run_check_output( 12 | "pyinfra -y --chdir examples @docker/ubuntu:22.04 apt.packages iftop update=true", 13 | expected_lines=["docker build complete"], 14 | ) 15 | -------------------------------------------------------------------------------- /tests/facts/brew.BrewTaps/taps.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "brew tap", 3 | "requires_command": "brew", 4 | "output": [ 5 | "homebrew/cask", 6 | "homebrew/apache" 7 | ], 8 | "fact": [ 9 | "homebrew/cask", 10 | "homebrew/apache" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/brew.BrewVersion/bad_output.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "brew --version", 3 | "requires_command": "brew", 4 | "output": [ 5 | "some random text" 6 | ], 7 | "fact": [0, 0, 0] 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/brew.BrewVersion/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "brew --version", 3 | "requires_command": "brew", 4 | "output": [ 5 | "Homebrew 3.1.7-62-g9f5afcb", 6 | "Homebrew/homebrew-core (git revision ccfbdb1968; last commit 2021-05-16)", 7 | "Homebrew/homebrew-cask (git revision c91eea78ff; last commit 2021-05-16)" 8 | ], 9 | "fact": [3,1,7] 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/cargo.CargoPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "cargo install --list", 3 | "requires_command": "cargo", 4 | "output": [ 5 | "vigil-server v1.25.2:", 6 | " vigil", 7 | "zee v0.4.0 (https://github.com/zee-editor/zee#08c9f31d):", 8 | " zee" 9 | ], 10 | "fact": { 11 | "vigil-server": ["1.25.2"], 12 | "zee": ["0.4.0"] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/facts/choco.ChocoVersion/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "choco --version", 3 | "output": ["0.10.15", ""], 4 | "fact": "0.10.15" 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/deb.DebPackage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "package-name", 3 | "command": "! test -e package-name && (dpkg -s package-name 2>/dev/null || true) || dpkg -I package-name", 4 | "requires_command": "dpkg", 5 | "output": [ 6 | "Package: package-name", 7 | "Version: 1" 8 | ], 9 | "fact": { 10 | "name": "package-name", 11 | "version": "1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/docker.DockerContainer/container.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myid", 3 | "command": "docker container inspect myid 2>&- || true", 4 | "requires_command": "docker", 5 | "output": [ 6 | "{\"hello\": \"world\"}" 7 | ], 8 | "fact": { 9 | "hello": "world" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/docker.DockerContainers/container.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ids=$(docker ps -qa) && [ -n \"$ids\" ] && docker container inspect $ids || echo \"[]\"", 3 | "requires_command": "docker", 4 | "output": ["{\"hello\": \"world\"}"], 5 | "fact": { 6 | "hello": "world" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/docker.DockerImages/images.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ids=$(docker images -q) && [ -n \"$ids\" ] && docker image inspect $ids || echo \"[]\"", 3 | "requires_command": "docker", 4 | "output": ["{\"hello\": \"world\"}"], 5 | "fact": { 6 | "hello": "world" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/efibootmgr.EFIBootMgr/not_uefi.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "efibootmgr || true", 3 | "requires_command": "efibootmgr", 4 | "output": [], 5 | "fact": null 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/files.Block/defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "/tmp/foo", 3 | "command": "awk '/# END PYINFRA BLOCK/{ f=0} f; /# BEGIN PYINFRA BLOCK/{ f=1} ' /tmp/foo || (find /tmp/foo -type f > /dev/null && echo __pyinfra_exists_/tmp/foo || echo __pyinfra_missing_/tmp/foo )", 4 | "output": [ 5 | "aaa", 6 | "bbb" 7 | ], 8 | "fact": [ 9 | "aaa", 10 | "bbb" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/files.Block/no_markers_found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "/tmp/foo", 3 | "command": "awk '/# END PYINFRA BLOCK/{ f=0} f; /# BEGIN PYINFRA BLOCK/{ f=1} ' /tmp/foo || (find /tmp/foo -type f > /dev/null && echo __pyinfra_exists_/tmp/foo || echo __pyinfra_missing_/tmp/foo )", 4 | "output": [ 5 | "__pyinfra_exists_/tmp/foo" 6 | ], 7 | "fact": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.Block/not_found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "/tmp/foo", 3 | "command": "awk '/# END PYINFRA BLOCK/{ f=0} f; /# BEGIN PYINFRA BLOCK/{ f=1} ' /tmp/foo || (find /tmp/foo -type f > /dev/null && echo __pyinfra_exists_/tmp/foo || echo __pyinfra_missing_/tmp/foo )", 4 | "output": [ 5 | "__pyinfra_missing_/tmp/foo" 6 | ], 7 | "fact": null 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.FindDirectories/directories.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "mydir", 3 | "command": "find mydir -type d || true", 4 | "output": [ 5 | "anotherdir" 6 | ], 7 | "fact": [ 8 | "anotherdir" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/files.FindFiles/files.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "mydir", 3 | "command": "find mydir -type f || true", 4 | "output": [ 5 | "myfile" 6 | ], 7 | "fact": [ 8 | "myfile" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/files.FindFiles/files_with_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": { 3 | "path": "mydir", 4 | "fname": "myfile" 5 | }, 6 | "command": "find mydir -type f -name myfile || true", 7 | "output": [ 8 | "myfile" 9 | ], 10 | "fact": [ 11 | "myfile" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/files.FindFiles/files_with_name_wildcard.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": { 3 | "path": "mydir", 4 | "fname": "myfile*" 5 | }, 6 | "command": "find mydir -type f -name 'myfile*' || true", 7 | "output": [ 8 | "myfile" 9 | ], 10 | "fact": [ 11 | "myfile" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/files.FindInFile/lines.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/home/pyinfra/mylink", "test"], 3 | "command": "grep -e test /home/pyinfra/mylink 2> /dev/null || ( find /home/pyinfra/mylink -type f > /dev/null && echo __pyinfra_exists_/home/pyinfra/mylink || true )", 4 | "output": [ 5 | "thing test thing", 6 | "another test" 7 | ], 8 | "fact": [ 9 | "thing test thing", 10 | "another test" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/files.FindInFile/no_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/home/pyinfra/mylink", "test"], 3 | "command": "grep -e test /home/pyinfra/mylink 2> /dev/null || ( find /home/pyinfra/mylink -type f > /dev/null && echo __pyinfra_exists_/home/pyinfra/mylink || true )", 4 | "output": null, 5 | "fact": null 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/files.FindInFile/no_matches.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/home/pyinfra/mylink", "test"], 3 | "command": "grep -e test /home/pyinfra/mylink 2> /dev/null || ( find /home/pyinfra/mylink -type f > /dev/null && echo __pyinfra_exists_/home/pyinfra/mylink || true )", 4 | "output": [ 5 | "__pyinfra_exists_/home/pyinfra/mylink" 6 | ], 7 | "fact": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.FindLinks/links.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "mydir", 3 | "command": "find mydir -type l || true", 4 | "output": [ 5 | "mylink" 6 | ], 7 | "fact": [ 8 | "mylink" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/files.Flags/bad_output.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/foo/bar/baz"], 3 | "requires_command": "chflags", 4 | "command": "! test -e /foo/bar/baz || stat -f %Sf /foo/bar/baz", 5 | "output": [ 6 | ",,," 7 | ], 8 | "fact": [ 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/files.Flags/no_flags_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/foo/bar/baz"], 3 | "requires_command": "chflags", 4 | "command": "! test -e /foo/bar/baz || stat -f %Sf /foo/bar/baz", 5 | "output": [ 6 | "" 7 | ], 8 | "fact": [ 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/files.Flags/no_output.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/foo/bar/baz"], 3 | "requires_command": "chflags", 4 | "command": "! test -e /foo/bar/baz || stat -f %Sf /foo/bar/baz", 5 | "output": [ 6 | ], 7 | "fact": [ 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/files.Flags/one_flag_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/foo/bar/baz"], 3 | "requires_command": "chflags", 4 | "command": "! test -e /foo/bar/baz || stat -f %Sf /foo/bar/baz", 5 | "output": [ 6 | "oneflag" 7 | ], 8 | "fact": [ 9 | "oneflag" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/files.Flags/too_much_output.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/foo/bar/baz"], 3 | "requires_command": "chflags", 4 | "command": "! test -e /foo/bar/baz || stat -f %Sf /foo/bar/baz", 5 | "output": [ 6 | "line one", 7 | "line two" 8 | ], 9 | "fact": [ 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/files.Flags/two_flags_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["/foo/bar/baz"], 3 | "requires_command": "chflags", 4 | "command": "! test -e /foo/bar/baz || stat -f %Sf /foo/bar/baz", 5 | "output": [ 6 | "oneflag,twoflag" 7 | ], 8 | "fact": [ 9 | "oneflag", 10 | "twoflag" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/files.Md5File/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myfile", 3 | "command": "test -e myfile && ( md5sum myfile 2> /dev/null || md5 myfile 2> /dev/null ) || true", 4 | "output": [ 5 | "c10ba97d7c9078a006d26b5db01d8ee7 myfile" 6 | ], 7 | "fact": "c10ba97d7c9078a006d26b5db01d8ee7" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.Md5File/file_bsd_style.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myfile", 3 | "command": "test -e myfile && ( md5sum myfile 2> /dev/null || md5 myfile 2> /dev/null ) || true", 4 | "output": [ 5 | "MD5 (myfile) = c10ba97d7c9078a006d26b5db01d8ee7" 6 | ], 7 | "fact": "c10ba97d7c9078a006d26b5db01d8ee7" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.Md5File/file_needs_quotes.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "my () file && special_chars.txt", 3 | "command": "test -e 'my () file && special_chars.txt' && ( md5sum 'my () file && special_chars.txt' 2> /dev/null || md5 'my () file && special_chars.txt' 2> /dev/null ) || true", 4 | "output": [ 5 | "c10ba97d7c9078a006d26b5db01d8ee7 my () file && special_chars.txt" 6 | ], 7 | "fact": "c10ba97d7c9078a006d26b5db01d8ee7" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.Sha1File/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myfile", 3 | "command": "test -e myfile && ( sha1sum myfile 2> /dev/null || shasum myfile 2> /dev/null || sha1 myfile 2> /dev/null ) || true", 4 | "output": [ 5 | "85746ef87ddabd9fdf4836c5835e34a030d2a141 myfile" 6 | ], 7 | "fact": "85746ef87ddabd9fdf4836c5835e34a030d2a141" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.Sha1File/file_bsd_style.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myfile", 3 | "command": "test -e myfile && ( sha1sum myfile 2> /dev/null || shasum myfile 2> /dev/null || sha1 myfile 2> /dev/null ) || true", 4 | "output": [ 5 | "SHA1 (myfile) = 85746ef87ddabd9fdf4836c5835e34a030d2a141" 6 | ], 7 | "fact": "85746ef87ddabd9fdf4836c5835e34a030d2a141" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.Sha256File/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myfile", 3 | "command": "test -e myfile && ( sha256sum myfile 2> /dev/null || shasum -a 256 myfile 2> /dev/null || sha256 myfile 2> /dev/null ) || true", 4 | "output": [ 5 | "3867882e8ccc16bd6a1e3e214a46608f9cf5d21687bbb8c25751da3c47b48033 myfile" 6 | ], 7 | "fact": "3867882e8ccc16bd6a1e3e214a46608f9cf5d21687bbb8c25751da3c47b48033" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/files.Sha256File/file_bsd_style.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myfile", 3 | "command": "test -e myfile && ( sha256sum myfile 2> /dev/null || shasum -a 256 myfile 2> /dev/null || sha256 myfile 2> /dev/null ) || true", 4 | "output": [ 5 | "SHA256 (myfile) = 3867882e8ccc16bd6a1e3e214a46608f9cf5d21687bbb8c25751da3c47b48033" 6 | ], 7 | "fact": "3867882e8ccc16bd6a1e3e214a46608f9cf5d21687bbb8c25751da3c47b48033" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/flatpak.FlatpakPackage/not_found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "not_found.test.test", 3 | "command": "flatpak info not_found.test.test", 4 | "requires_command": "flatpak", 5 | "output": [ 6 | "error: not_found.test.test/*unspecified*/*unspecified* not installed" 7 | ], 8 | "fact": {} 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/freebsd.PkgPackage/package-with-jail.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": { 3 | "package" : "screen", 4 | "jail" : "nginx" 5 | }, 6 | "command": "pkg -j nginx info -E -- screen 2> /dev/null || true", 7 | "output": [ 8 | "screen-4.9.1_5" 9 | ], 10 | "fact": "screen-4.9.1_5" 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/freebsd.PkgPackage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "screen", 3 | "command": "pkg info -E -- screen 2> /dev/null || true", 4 | "output": [ 5 | "screen-4.9.1_5" 6 | ], 7 | "fact": "screen-4.9.1_5" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/freebsd.ServiceScript/found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "supervisord", 3 | "command": "for service in `service -j '' -l`; do if [ supervisord = \"$service\" ]; then echo \"$service\"; fi; done", 4 | "output": [ 5 | "supervisord" 6 | ], 7 | "fact": "supervisord" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/freebsd.ServiceScript/not-found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "not-found-service", 3 | "command": "for service in `service -j '' -l`; do if [ not-found-service = \"$service\" ]; then echo \"$service\"; fi; done", 4 | "output": [], 5 | "fact": "" 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/freebsd.ServiceStatus/not-running.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "nginx", 3 | "command": "service -j '' nginx status > /dev/null 2>&1; if [ $? -eq 0 ]; then echo running; fi", 4 | "output": [], 5 | "fact": "" 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/freebsd.ServiceStatus/running.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "memcached", 3 | "command": "service -j '' memcached status > /dev/null 2>&1; if [ $? -eq 0 ]; then echo running; fi", 4 | "output": [ 5 | "running" 6 | ], 7 | "fact": "running" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/freebsd.Sysrc/found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg" : "memcached_enable", 3 | "command": "sysrc -in -- memcached_enable || true", 4 | "output": [ 5 | "YES" 6 | ], 7 | "fact": "YES" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/freebsd.Sysrc/not-found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg" : "memcached_enable", 3 | "command": "sysrc -in -- memcached_enable || true", 4 | "output": [], 5 | "fact": "" 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/gem.GemPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "gem list --local", 3 | "requires_command": "gem", 4 | "output": [ 5 | "pydash (3.48)" 6 | ], 7 | "fact": { 8 | "pydash": ["3.48"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/git.GitBranch/branch.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myrepo", 3 | "command": "! test -d myrepo || (cd myrepo && git describe --all)", 4 | "requires_command": "git", 5 | "output": [ 6 | "heads/develop" 7 | ], 8 | "fact": "develop" 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/git.GitConfig/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "git config --global -l || true", 3 | "requires_command": "git", 4 | "output": [ 5 | "user.email=nick@gmail.com" 6 | ], 7 | "fact": { 8 | "user.email": ["nick@gmail.com"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/git.GitConfig/multi_value.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "git config --global -l || true", 3 | "requires_command": "git", 4 | "output": [ 5 | "safe.directory=/a/safe/repo", 6 | "safe.directory=/another/safe/repo" 7 | ], 8 | "fact": { 9 | "safe.directory": [ 10 | "/a/safe/repo", 11 | "/another/safe/repo" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/facts/git.GitConfig/repo.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myrepo", 3 | "command": "! test -d myrepo || (cd myrepo && git config --local -l)", 4 | "requires_command": "git", 5 | "output": [ 6 | "user.email=nick@gmail.com" 7 | ], 8 | "fact": { 9 | "user.email": ["nick@gmail.com"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/git.GitTag/tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myrepo", 3 | "command": "! test -d myrepo || (cd myrepo && git tag)", 4 | "requires_command": "git", 5 | "output": [ 6 | "v1.0.0", 7 | "v1.0.1" 8 | ], 9 | "fact": [ 10 | "v1.0.0", 11 | "v1.0.1" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/git.GitTrackingBranch/branch.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myrepo", 3 | "command": "! test -d myrepo || (cd myrepo && git status --branch --porcelain)", 4 | "requires_command": "git", 5 | "output": [ 6 | "## branch1...origin/master" 7 | ], 8 | "fact": "origin/master" 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/git.GitTrackingBranch/branch_behind.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myrepo", 3 | "command": "! test -d myrepo || (cd myrepo && git status --branch --porcelain)", 4 | "requires_command": "git", 5 | "output": [ 6 | "## branch1...origin/master [behind 692]" 7 | ], 8 | "fact": "origin/master" 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/git.GitTrackingBranch/no_branch.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "myrepo", 3 | "command": "! test -d myrepo || (cd myrepo && git status --branch --porcelain)", 4 | "requires_command": "git", 5 | "output": [ 6 | "## branch1" 7 | ], 8 | "fact": null 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/hardware.Cpus/invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "getconf NPROCESSORS_ONLN 2> /dev/null || getconf _NPROCESSORS_ONLN", 3 | "output": ["nope"], 4 | "fact": null 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/hardware.Cpus/valid.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "getconf NPROCESSORS_ONLN 2> /dev/null || getconf _NPROCESSORS_ONLN", 3 | "output": ["1"], 4 | "fact": 1 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/npm.NpmPackages/local_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "somedir", 3 | "command": "cd somedir && npm list -g --depth=0", 4 | "requires_command": "npm", 5 | "output": [ 6 | "├── pydash@3.48", 7 | "└── thing@1.9" 8 | ], 9 | "fact": { 10 | "pydash": ["3.48"], 11 | "thing": ["1.9"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/npm.NpmPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "npm list -g --depth=0", 3 | "requires_command": "npm", 4 | "output": [ 5 | "├── pydash@3.48", 6 | "└── thing@1.9" 7 | ], 8 | "fact": { 9 | "pydash": ["3.48"], 10 | "thing": ["1.9"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/pip.Pip3Packages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "pip3 freeze --all", 3 | "requires_command": "pip3", 4 | "output": [ 5 | "pydash==3.48" 6 | ], 7 | "fact": { 8 | "pydash": ["3.48"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/pip.PipPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "pip freeze --all", 3 | "requires_command": "pip", 4 | "output": [ 5 | "pydash==3.48" 6 | ], 7 | "fact": { 8 | "pydash": ["3.48"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/pip.PipPackages/packages_pip3.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "pip3", 3 | "command": "pip3 freeze --all", 4 | "requires_command": "pip3", 5 | "output": [ 6 | "pydash==3.48" 7 | ], 8 | "fact": { 9 | "pydash": ["3.48"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/pipx.PipxPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "pipx list --short", 3 | "requires_command": "pipx", 4 | "output": [ 5 | "copier 9.0.1", 6 | "invoke 2.2.0" 7 | ], 8 | "fact": { 9 | "copier": ["9.0.1"], 10 | "invoke": ["2.2.0"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/pkg.PkgPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "pkg info || pkg_info || true", 3 | "output": [ 4 | "nano-3.48" 5 | ], 6 | "fact": { 7 | "nano": ["3.48"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/podman.PodmanPs/empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "podman ps --format=json --all", 3 | "requires_command": "podman", 4 | "output": [ 5 | "[]" 6 | ], 7 | "fact": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/rpm.RpmPackageProvides/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "vim", 3 | "command": "repoquery --queryformat '%{NAME} %{VERSION}-%{RELEASE}\\n' --whatprovides vim || true", 4 | "requires_command": "repoquery", 5 | "output": [ 6 | "vim-enhanced 8.0.1763-15.el8" 7 | ], 8 | "fact": [ 9 | ["vim-enhanced", "8.0.1763-15.el8"] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/rpm.RpmPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "rpm --queryformat '%{NAME} %{VERSION}-%{RELEASE}\\n' -qa", 3 | "requires_command": "rpm", 4 | "output": [ 5 | "pydash 3.48.0" 6 | ], 7 | "fact": { 8 | "pydash": ["3.48.0"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/runit.RunitManaged/single.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["agetty-tty1", "/var/service"], 3 | "command": "cd \"/var/service\" && test -h \"agetty-tty1\" && echo \"agetty-tty1\" || true", 4 | "requires_command": "sv", 5 | "output": [ 6 | "agetty-tty1" 7 | ], 8 | "fact": [ 9 | "agetty-tty1" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/runit.RunitStatus/single.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["agetty-tty1", "/var/service"], 3 | "command": "SVDIR=\"/var/service\" sv status \"agetty-tty1\"", 4 | "requires_command": "sv", 5 | "output": [ 6 | "run: agetty-tty1: (pid 1160) 1214497s" 7 | ], 8 | "fact": { 9 | "agetty-tty1": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/selinux.FileContext/file_context.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "/etc/hosts", 3 | "command": "stat -c %C /etc/hosts || exit 0", 4 | "output": [ 5 | "system_u:object_r:net_conf_t:s0" 6 | ], 7 | "fact": { 8 | "user":"system_u", 9 | "role": "object_r", 10 | "type": "net_conf_t", 11 | "level": "s0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/selinux.FileContextMapping/not_found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "/etc/etc/etc/etc/etc/etc", 3 | "requires_command": "semanage", 4 | "command": "set -o pipefail && semanage fcontext -n -l | (grep '^/etc/etc/etc/etc/etc/etc' || true)", 5 | "output": [ 6 | ], 7 | "fact": {} 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEBoolean/get.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "some_boolean", 3 | "requires_command": "getsebool", 4 | "command": "getsebool some_boolean", 5 | "output": [ 6 | "some_boolean --> off" 7 | ], 8 | "fact": "off" 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEPort/generic_and_specific.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["tcp", 22], 3 | "requires_command": "sepolicy", 4 | "command": "(sepolicy network -p 22 2>/dev/null || true) | grep tcp", 5 | "output": [ 6 | "22: tcp ssh_port_t 22", 7 | "22: tcp reserved_port_t 1-511" 8 | ], 9 | "fact": "ssh_port_t" 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEPort/get_bad_port.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["tcp","portname"], 3 | "requires_command": "sepolicy", 4 | "command": "(sepolicy network -p portname 2>/dev/null || true) | grep tcp", 5 | "output": [ 6 | ], 7 | "fact": "" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEPort/only_generic.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["tcp", 9997], 3 | "requires_command": "sepolicy", 4 | "command": "(sepolicy network -p 9997 2>/dev/null || true) | grep tcp", 5 | "output": [ 6 | "9997: tcp unreserved_port_t 1024-32767" 7 | ], 8 | "fact": "" 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEPorts/line_noise_input.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires_command": "semanage", 3 | "command": "semanage port -ln", 4 | "output": [ 5 | "!$%(*&Q#(*&%_)*Q%#(*Q)%@#(*&Q)@(*$)Q(*@$)(*)(Q@*$()*Q@$)" 6 | ], 7 | "fact": {} 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEPorts/multiple_single_ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires_command": "semanage", 3 | "command": "semanage port -ln", 4 | "output": [ 5 | "example_port_t tcp 20,30,40" 6 | ], 7 | "fact": { 8 | "tcp": { "20": "example_port_t", "30": "example_port_t", "40": "example_port_t"} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEPorts/only_single_port.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires_command": "semanage", 3 | "command": "semanage port -ln", 4 | "output": [ 5 | "example_port_t sctp 99" 6 | ], 7 | "fact": { 8 | "sctp": { "99": "example_port_t"} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/selinux.SEPorts/single_and_range.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires_command": "semanage", 3 | "command": "semanage port -ln", 4 | "output": [ 5 | "example_port_t tcp 93, 50-51" 6 | ], 7 | "fact": { 8 | "tcp": {"93": "example_port_t", "50": "example_port_t", "51": "example_port_t"} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/server.Arch/arch.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "uname -m", 3 | "output": ["x86_64"], 4 | "fact": "x86_64" 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/server.Command/command.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "some-command", 3 | "command": "some-command", 4 | "output": ["a", "nop"], 5 | "fact": "a\nnop" 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/server.Date/date.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "date +'%Y-%m-%dT%H:%M:%S%z'", 3 | "output": ["2019-01-01T00:00:00+0000"], 4 | "fact": "2019-01-01T00:00:00+00:00" 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/server.Groups/groups.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "cat /etc/group", 3 | "output": [ 4 | "lpadmin:x:114:vagrant", 5 | "sambashare:x:115:vagrant", 6 | "vboxsf:x:999:" 7 | ], 8 | "fact": [ 9 | "lpadmin", 10 | "sambashare", 11 | "vboxsf" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/server.HasGui/gui_absent.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ls /usr/bin/*session || true", 3 | "output": [], 4 | "fact": false 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/server.HasGui/gui_present.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ls /usr/bin/*session || true", 3 | "output": [ 4 | "/usr/bin/gnome-session" 5 | ], 6 | "fact": true 7 | } 8 | -------------------------------------------------------------------------------- /tests/facts/server.Home/home.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "echo ~", 3 | "output": ["/home/pyinfra"], 4 | "fact": "/home/pyinfra" 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/server.Home/root.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["root"], 3 | "command": "echo ~root", 4 | "output": ["/root"], 5 | "fact": "/root" 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/server.Home/some_user.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": ["some_user"], 3 | "command": "echo ~some_user", 4 | "output": ["/home/some_user"], 5 | "fact": "/home/some_user" 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/server.Hostname/hostname.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "uname -n", 3 | "output": ["my-host.net"], 4 | "fact": "my-host.net" 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/server.LinuxDistribution/no_match.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "cd /etc/ && for file in $(ls -pdL *-release | grep -v /); do echo \"/etc/${file}\"; cat \"/etc/${file}\"; echo ---; done", 3 | "output": [], 4 | "fact": { 5 | "name": null, 6 | "major": null, 7 | "minor": null, 8 | "release_meta": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/server.LinuxGui/gnome_present.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ls /usr/bin/*session || true", 3 | "output": [ 4 | "/usr/bin/gnome-session" 5 | ], 6 | "fact": ["GNOME"] 7 | } 8 | -------------------------------------------------------------------------------- /tests/facts/server.LinuxName/ubuntu.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "cd /etc/ && for file in $(ls -pdL *-release | grep -v /); do echo \"/etc/${file}\"; cat \"/etc/${file}\"; echo ---; done", 3 | "output": [ 4 | "/etc/os-release", 5 | "NAME=\"Ubuntu\"" 6 | ], 7 | "fact": "Ubuntu" 8 | } 9 | -------------------------------------------------------------------------------- /tests/facts/server.Locales: -------------------------------------------------------------------------------- 1 | { 2 | "command": "locale -a ", 3 | "output": [ 4 | "C", 5 | "C.UTF-8", 6 | "en_US.utf8", 7 | "fr_FR.utf8", 8 | "POSIX" 9 | ], 10 | "fact": [ 11 | "C", 12 | "C.UTF-8", 13 | "en_US.UTF-8", 14 | "fr_FR.UTF-8", 15 | "POSIX" 16 | ] 17 | } -------------------------------------------------------------------------------- /tests/facts/server.Os/os.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "uname -s", 3 | "output": ["os"], 4 | "fact": "os" 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/server.OsVersion/os_version.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "uname -r", 3 | "output": ["os_version"], 4 | "fact": "os_version" 5 | } 6 | -------------------------------------------------------------------------------- /tests/facts/server.Port/empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ss -lptnH 'src :53'", 3 | "arg": 53, 4 | "requires_command": "ss", 5 | "output": [], 6 | "fact": [null, null] 7 | } 8 | -------------------------------------------------------------------------------- /tests/facts/server.Port/one-process.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ss -lptnH 'src :10025'", 3 | "arg": 10025, 4 | "requires_command": "ss", 5 | "output": [ 6 | "LISTEN 0 100 127.0.0.1:10025 0.0.0.0:* users:((\"smtpd\",pid=3927036,fd=6),(\"master\",pid=1997758,fd=97))" 7 | ], 8 | "fact": [ 9 | "smtpd", 10 | 3927036 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/server.Selinux/no-output.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "sestatus", 3 | "requires_command": "sestatus", 4 | "output": [ 5 | "" 6 | ], 7 | "fact": { 8 | "mode": null 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/server.Selinux/selinux.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "sestatus", 3 | "requires_command": "sestatus", 4 | "output": [ 5 | "SELinux status: enabled", 6 | "SELinuxfs mount: /selinux" 7 | ], 8 | "fact": { 9 | "mode": "enabled" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/facts/server.Sysctl/sysctl_linux.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "sysctl -a", 3 | "output": [ 4 | "vm.nr_hugepages_mempolicy = 0", 5 | "nope what", 6 | "vm.nr_overcommit_hugepages = 0" 7 | ], 8 | "fact": { 9 | "vm.nr_hugepages_mempolicy": 0, 10 | "vm.nr_overcommit_hugepages": 0 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/server.Sysctl/sysctl_macos.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "sysctl -a", 3 | "output": [ 4 | "security.mac.sysvmsg_enforce: 1", 5 | "security.mac.sysvsem_enforce: 1", 6 | "security.mac.sysvshm_enforce: 1" 7 | ], 8 | "fact": { 9 | "security.mac.sysvmsg_enforce": 1, 10 | "security.mac.sysvsem_enforce": 1, 11 | "security.mac.sysvshm_enforce": 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/facts/server.Which/which.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "python", 3 | "command": "command -v python || true", 4 | "output": ["/usr/local/bin/python"], 5 | "fact": "/usr/local/bin/python" 6 | } 7 | -------------------------------------------------------------------------------- /tests/facts/snap.SnapPackage/not_found.json: -------------------------------------------------------------------------------- 1 | { 2 | "arg": "foo", 3 | "command": "snap info foo", 4 | "requires_command": "snap", 5 | "output": [ 6 | "error: no snap found for \"foo\"" 7 | ], 8 | "fact": {} 9 | } 10 | -------------------------------------------------------------------------------- /tests/facts/sysvinit.InitdStatus/services.json: -------------------------------------------------------------------------------- 1 | { 2 | "output": [ 3 | "rpcsvcgssd=0", 4 | "rsyslog=4", 5 | "saslauthd=3" 6 | ], 7 | "fact": { 8 | "rpcsvcgssd": true, 9 | "rsyslog": null, 10 | "saslauthd": false 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/upstart.UpstartStatus/services.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "initctl list", 3 | "requires_command": "initctl", 4 | "output": [ 5 | "something start/running, process 1493", 6 | "plymouth-shutdown stop/waiting" 7 | ], 8 | "fact": { 9 | "something": true, 10 | "plymouth-shutdown": false 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/facts/vzctl.OpenvzContainers/containers.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "vzlist -a -j", 3 | "requires_command": "vzlist", 4 | "output": [ 5 | "[{\"ctid\": 100},", 6 | "{\"ctid\": 101, \"somekey\": 10}]" 7 | ], 8 | "fact": { 9 | "100": {}, 10 | "101": { 11 | "somekey": 10 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/facts/xbps.XbpsPackages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "xbps-query -l", 3 | "requires_command": "xbps-query", 4 | "output": [ 5 | "ii vim-8.2.0891_1 Vim editor (vi clone)" 6 | ], 7 | "fact": { 8 | "vim": ["8.2.0891_1"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/facts/zfs.Pools/pools.yaml: -------------------------------------------------------------------------------- 1 | command: zpool get -H all 2 | requires_command: zpool 3 | output: | 4 | tank compression lz4 - 5 | tank ashift 12 local 6 | fact: 7 | tank: 8 | compression: lz4 9 | ashift: '12' 10 | -------------------------------------------------------------------------------- /tests/facts/zypper.ZypperRepositories/repos.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "cat /etc/zypp/repos.d/*.repo || true", 3 | "requires_command": "zypper", 4 | "output": [ 5 | "# comment line", 6 | " # comment line with whitespaces", 7 | "[somerepo]", 8 | "baseurl=abc" 9 | 10 | ], 11 | "fact": [ 12 | { 13 | "name": "somerepo", 14 | "baseurl": "abc" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/apk.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "facts": { 4 | "apk.ApkPackages": {} 5 | }, 6 | "commands": [ 7 | "apk add curl" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/apk.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["curl", "i-dont-exist"]], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "apk.ApkPackages": { 8 | "curl": "1" 9 | } 10 | }, 11 | "commands": [ 12 | "apk del curl" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/apk.packages/upgrade_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": { 4 | "latest": true 5 | }, 6 | "facts": { 7 | "apk.ApkPackages": {} 8 | }, 9 | "commands": [ 10 | "apk add curl" 11 | ], 12 | "idempotent": false, 13 | "disable_idempotent_warning_reason": "package upgrades are always executed" 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/apk.upgrade/upgrade_available.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "kwargs": { 4 | "available": true 5 | }, 6 | "commands": [ 7 | "apk upgrade --available" 8 | ], 9 | "idempotent": false 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/apt.dist_upgrade/dist_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "commands": [ 4 | "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" dist-upgrade" 5 | ], 6 | "facts": { 7 | "apt.SimulateOperationWillChange": { 8 | "command=dist-upgrade": {} 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["mykey"], 3 | "facts": { 4 | "apt.AptKeys": {}, 5 | "gpg.GpgKey": { 6 | "src=mykey": { 7 | "abc": {} 8 | } 9 | } 10 | }, 11 | "commands": [ 12 | "apt-key add mykey" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["mykey"], 3 | "facts": { 4 | "apt.AptKeys": { 5 | "abc": {} 6 | }, 7 | "gpg.GpgKey": { 8 | "src=mykey": { 9 | "abc": {} 10 | } 11 | } 12 | }, 13 | "commands": [], 14 | "noop_description": "All keys from mykey are already available in the apt keychain" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_keyserver.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "keyserver": "key-server.net", 4 | "keyid": "abc" 5 | }, 6 | "facts": { 7 | "apt.AptKeys": {} 8 | }, 9 | "commands": [ 10 | "apt-key adv --keyserver key-server.net --recv-keys abc" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_keyserver_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "keyserver": "key-server.net", 4 | "keyid": ["abc", "def"] 5 | }, 6 | "facts": { 7 | "apt.AptKeys": { 8 | "abc": {}, 9 | "def": {} 10 | } 11 | }, 12 | "commands": [], 13 | "noop_description": "Keys abc, def are already available in the apt keychain" 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_keyserver_multiple.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "keyserver": "key-server.net", 4 | "keyid": ["abc", "def"] 5 | }, 6 | "facts": { 7 | "apt.AptKeys": {} 8 | }, 9 | "commands": [ 10 | "apt-key adv --keyserver key-server.net --recv-keys abc def" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_keyserver_multiple_partial.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "keyserver": "key-server.net", 4 | "keyid": ["abc", "def"] 5 | }, 6 | "facts": { 7 | "apt.AptKeys": { 8 | "abc": {} 9 | } 10 | }, 11 | "commands": [ 12 | "apt-key adv --keyserver key-server.net --recv-keys def" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_keyserver_no_keyid.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "keyserver": "key-server.net" 4 | }, 5 | "facts": { 6 | "apt.AptKeys": {} 7 | }, 8 | "exception": { 9 | "name": "OperationError", 10 | "message": "`keyid` must be provided with `keyserver`" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_no_gpg.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["mykey"], 3 | "facts": { 4 | "apt.AptKeys": {}, 5 | "gpg.GpgKey": { 6 | "src=mykey": null 7 | } 8 | }, 9 | "commands": [ 10 | "apt-key add mykey" 11 | ], 12 | "idempotent": false, 13 | "disable_idempotent_warning_reason": "the key will always be added if gpg cant check whether it exists" 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/apt.key/add_url.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["http://mykey"], 3 | "facts": { 4 | "apt.AptKeys": {}, 5 | "gpg.GpgKey": { 6 | "src=http://mykey": { 7 | "abc": {} 8 | } 9 | } 10 | }, 11 | "commands": [ 12 | "(wget -O - http://mykey || curl -sSLf http://mykey) | apt-key add -" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/apt.packages/add_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["git"], 3 | "facts": { 4 | "deb.DebPackages": {} 5 | }, 6 | "commands": [ 7 | "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install git" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/apt.packages/add_package_allow_downgrades.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["git"], 3 | "kwargs": { 4 | "allow_downgrades": true 5 | }, 6 | "facts": { 7 | "deb.DebPackages": {} 8 | }, 9 | "commands": [ 10 | "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install --allow-downgrades git" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/apt.packages/add_package_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["git"], 3 | "kwargs": { 4 | "force": true 5 | }, 6 | "facts": { 7 | "deb.DebPackages": {} 8 | }, 9 | "commands": [ 10 | "DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install git" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/apt.packages/add_package_no_recommends.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["git"], 3 | "kwargs": { 4 | "no_recommends": true 5 | }, 6 | "facts": { 7 | "deb.DebPackages": {} 8 | }, 9 | "commands": [ 10 | "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install --no-install-recommends git" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/apt.packages/install_with_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["git"], 3 | "kwargs": { 4 | "extra_install_args": "--extra-install-arg" 5 | }, 6 | "facts": { 7 | "deb.DebPackages": {} 8 | }, 9 | "commands": [ 10 | "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" install --extra-install-arg git" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/apt.ppa/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["ppa:some-repo"], 3 | "facts": { 4 | "apt_sources": {}, 5 | "find_in_file:/etc/apt/sources.list": false 6 | }, 7 | "commands": [ 8 | "apt-add-repository -y \"ppa:some-repo\"" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/apt.ppa/remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["ppa:some-repo"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "apt_sources": { 8 | "http://ppa.launchpad.net/some-repo/ubuntu": {} 9 | }, 10 | "find_in_file:/etc/apt/sources.list": false 11 | }, 12 | "commands": [ 13 | "apt-add-repository -y --remove \"ppa:some-repo\"" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/apt.upgrade/upgrade_autoremove.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": {"auto_remove": true}, 3 | "commands": [ 4 | "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" upgrade --autoremove" 5 | ], 6 | "facts": { 7 | "apt.SimulateOperationWillChange": { 8 | "command=upgrade --autoremove": {} 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/brew.cask_upgrade/new_cli_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "facts": {"brew.BrewVersion": [2, 6, 0]}, 4 | "commands": [ 5 | "brew upgrade --cask" 6 | ], 7 | "idempotent": false 8 | } 9 | -------------------------------------------------------------------------------- /tests/operations/brew.cask_upgrade/old_cli_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "facts": {"brew.BrewVersion": [2,5,3]}, 4 | "commands": [ 5 | "brew cask upgrade" 6 | ], 7 | "idempotent": false 8 | } 9 | -------------------------------------------------------------------------------- /tests/operations/brew.casks/new_cli_add_casks.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["keepassxc"], 3 | "facts": { 4 | "brew.BrewCasks": {}, 5 | "brew.BrewVersion": [2, 6, 0] 6 | }, 7 | "commands": ["brew install --cask keepassxc"] 8 | } 9 | -------------------------------------------------------------------------------- /tests/operations/brew.casks/old_cli_add_casks.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["keepassxc"], 3 | "facts": { 4 | "brew.BrewCasks": {}, 5 | "brew.BrewVersion": [2, 5, 3] 6 | }, 7 | "commands": [ 8 | "brew cask install keepassxc" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/brew.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["php"], 3 | "facts": { 4 | "brew.BrewPackages": {} 5 | }, 6 | "commands": [ 7 | "brew install php" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/brew.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["php", "i-dont-exist"]], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "brew.BrewPackages": { 8 | "php": "1" 9 | } 10 | }, 11 | "commands": [ 12 | "brew uninstall php" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/add_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["homebrew/cask"], 3 | "facts": { 4 | "brew.BrewTaps": [ 5 | "homebrew/cask" 6 | ] 7 | }, 8 | "commands": [], 9 | "noop_description": "tap homebrew/cask already exists" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/add_tap.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["homebrew/cask"], 3 | "facts": { 4 | "brew.BrewTaps": [] 5 | }, 6 | "commands": [ 7 | "brew tap homebrew/cask" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/add_tap_bad_url.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "kwargs": { 4 | "url": "https://github.com/foo" 5 | }, 6 | "facts": { 7 | "brew.BrewTaps": [] 8 | }, 9 | "commands": [], 10 | "noop_description": "src 'foo' doesn't have two components." 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/add_tap_no_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "kwargs": {}, 4 | "facts": { 5 | "brew.BrewTaps": [] 6 | }, 7 | "commands": [], 8 | "noop_description": "no tap was specified" 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/add_tap_url.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ 3 | "homebrew/cask" 4 | ], 5 | "kwargs": { 6 | "url": "https://github.com/homebrew/cask" 7 | }, 8 | "facts": { 9 | "brew.BrewTaps": [] 10 | }, 11 | "commands": [ 12 | "brew tap homebrew/cask https://github.com/homebrew/cask" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/add_tap_url_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ 3 | "homebrew/cask" 4 | ], 5 | "kwargs": { 6 | "url": "https://github.com/homebrew/cask" 7 | }, 8 | "facts": { 9 | "brew.BrewTaps": [ 10 | "homebrew/cask" 11 | ] 12 | }, 13 | "commands": [], 14 | "noop_description": "tap homebrew/cask already exists" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/add_tap_url_no_src.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "kwargs": { 4 | "url": "https://github.com/homebrew/cask" 5 | }, 6 | "facts": { 7 | "brew.BrewTaps": [] 8 | }, 9 | "commands": ["brew tap homebrew/cask https://github.com/homebrew/cask"] 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/remove_no_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["homebrew/cask"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "brew.BrewTaps": [] 8 | }, 9 | "commands": [], 10 | "noop_description": "tap homebrew/cask does not exist" 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/brew.tap/remove_tap.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["homebrew/cask"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "brew.BrewTaps": [ 8 | "homebrew/cask" 9 | ] 10 | }, 11 | "commands": [ 12 | "brew untap homebrew/cask" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/brew.upgrade/upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "commands": [ 4 | "brew upgrade" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /tests/operations/bsdinit.service/skip_started.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "facts": { 4 | "server.Os": "FreeBSD", 5 | "bsdinit.RcdStatus": { 6 | "nginx": true 7 | } 8 | }, 9 | "commands": [], 10 | "noop_description": "service nginx is running" 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/bsdinit.service/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "facts": { 4 | "server.Os": "FreeBSD", 5 | "bsdinit.RcdStatus": { 6 | "nginx": false 7 | } 8 | }, 9 | "commands": [ 10 | "test -e /etc/rc.d/nginx && /etc/rc.d/nginx start || /usr/local/etc/rc.d/nginx start" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/bsdinit.service/stop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "kwargs": { 4 | "running": false 5 | }, 6 | "facts": { 7 | "server.Os": "FreeBSD", 8 | "bsdinit.RcdStatus": { 9 | "nginx": true 10 | } 11 | }, 12 | "commands": [ 13 | "test -e /etc/rc.d/nginx && /etc/rc.d/nginx stop || /usr/local/etc/rc.d/nginx stop" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/cargo.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["git@1.1", "react", "test@1.1"]], 3 | "facts": { 4 | "cargo.CargoPackages": { 5 | "git": ["1.0"], 6 | "test": ["1.1"] 7 | } 8 | }, 9 | "commands": [ 10 | "cargo install git@1.1 react" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/choco.install/install.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands": [ 3 | "Set-ExecutionPolicy Bypass -Scope Process -Force ;iex ((New-Object System.Net.WebClient).DownloadString(\"https://chocolatey.org/install.ps1\"))" 4 | ], 5 | "idempotent": false 6 | } 7 | -------------------------------------------------------------------------------- /tests/operations/choco.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["notepadplusplus"], 3 | "facts": { 4 | "choco.ChocoPackages": {} 5 | }, 6 | "commands": [ 7 | "choco install -y notepadplusplus" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/choco.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["notepadplusplus"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "choco.ChocoPackages": { 8 | "notepadplusplus": true 9 | } 10 | }, 11 | "commands": [ 12 | "choco uninstall -y -x notepadplusplus" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/crontab.crontab/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["this_is_a_command"], 3 | "facts": { 4 | "crontab.Crontab": { 5 | "user=None": {} 6 | } 7 | }, 8 | "commands": [ 9 | "echo '* * * * * this_is_a_command' >> _tempfile_", 10 | "crontab _tempfile_" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/crontab.crontab/add_special_time.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["this_is_a_command"], 3 | "kwargs": { 4 | "special_time": "@reboot" 5 | }, 6 | "facts": { 7 | "crontab.Crontab": { 8 | "user=None": {} 9 | } 10 | }, 11 | "commands": [ 12 | "echo '@reboot this_is_a_command' >> _tempfile_", 13 | "crontab _tempfile_" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/crontab.crontab/add_user.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["this_is_a_command"], 3 | "kwargs": { 4 | "user": "pyinfra" 5 | }, 6 | "facts": { 7 | "crontab.Crontab": { 8 | "user=pyinfra": {} 9 | } 10 | }, 11 | "commands": [ 12 | "echo '* * * * * this_is_a_command' >> _tempfile_", 13 | "crontab -u pyinfra _tempfile_" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/dnf.key/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["mykey"], 3 | "commands": [ 4 | "rpm --import mykey" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /tests/operations/dnf.packages/install_with_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ "docker-ce"], 3 | "kwargs": { 4 | "extra_install_args": "--foo" 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {}, 8 | "rpm.RpmPackageProvides": { 9 | "package=docker-ce": null 10 | } 11 | }, 12 | "commands": [ 13 | "dnf install -y --foo docker-ce" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/dnf.packages/install_with_nobest.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ "docker-ce"], 3 | "kwargs": { 4 | "nobest": "true" 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {}, 8 | "rpm.RpmPackageProvides": { 9 | "package=docker-ce": null 10 | } 11 | }, 12 | "commands": [ 13 | "dnf install -y --nobest docker-ce" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/dnf.packages/noop_add_package_alias.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["vim"]], 3 | "facts": { 4 | "rpm.RpmPackages": { 5 | "vim-enhanced": ["abc"] 6 | }, 7 | "rpm.RpmPackageProvides": { 8 | "package=vim": [["vim-enhanced", "abc"]] 9 | } 10 | }, 11 | "commands": [], 12 | "noop_description": "package vim is installed" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/dnf.packages/update_clean.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "update": true, 4 | "clean": true 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {}, 8 | "rpm.RpmPackageProvides": {} 9 | }, 10 | "commands": [ 11 | "dnf clean all", 12 | "dnf update -y" 13 | ], 14 | "idempotent": false, 15 | "disable_idempotent_warning_reason": "package upgrades are always executed" 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/dnf.repo/remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somerepo"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "files.File": { 8 | "path=/etc/yum.repos.d/somerepo.repo": { 9 | "mode": 0 10 | } 11 | } 12 | }, 13 | "commands": ["rm -f /etc/yum.repos.d/somerepo.repo"] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/dnf.rpm/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["something.rpm"], 3 | "facts": { 4 | "rpm.RpmPackages": {}, 5 | "rpm.RpmPackage": { 6 | "package=something.rpm": { 7 | "name": "something", 8 | "version": "abc" 9 | }, 10 | "package=something": null 11 | } 12 | }, 13 | "commands": [ 14 | "rpm -i something.rpm" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/dnf.rpm/add_existing_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["something.rpm"], 3 | "facts": { 4 | "rpm.RpmPackage": { 5 | "package=something.rpm": { 6 | "name": "something", 7 | "version": "1.1" 8 | }, 9 | "package=something": { 10 | "version": "1.0" 11 | } 12 | } 13 | }, 14 | "commands": ["rpm -i something.rpm"] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/docker.image/pull_image.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "image": "nginx:alpine", 4 | "present": true 5 | }, 6 | "facts": { 7 | "docker.DockerImages": [] 8 | }, 9 | "commands": [ 10 | "docker image pull nginx:alpine" 11 | ] 12 | } -------------------------------------------------------------------------------- /tests/operations/docker.image/remove_image.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "image": "nginx:alpine", 4 | "present": false 5 | }, 6 | "facts": { 7 | "docker.DockerImages": [] 8 | }, 9 | "commands": [ 10 | "docker image rm nginx:alpine" 11 | ] 12 | } -------------------------------------------------------------------------------- /tests/operations/docker.network/add_network.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "network": "nginx", 4 | "ingress": true, 5 | "attachable": true, 6 | "present": true 7 | }, 8 | "facts": { 9 | "docker.DockerNetwork": { 10 | "object_id=nginx": [] 11 | } 12 | }, 13 | "commands": [ 14 | "docker network create nginx --ingress --attachable" 15 | ] 16 | } -------------------------------------------------------------------------------- /tests/operations/docker.network/add_network_with_gateway.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "network": "nginx", 4 | "gateway": "192.168.0.1", 5 | "present": true 6 | }, 7 | "facts": { 8 | "docker.DockerNetwork": { 9 | "object_id=nginx": [] 10 | } 11 | }, 12 | "commands": [ 13 | "docker network create nginx --gateway 192.168.0.1" 14 | ] 15 | } -------------------------------------------------------------------------------- /tests/operations/docker.network/add_network_with_ip_range.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "network": "nginx", 4 | "ip_range": "192.168.0.100/24", 5 | "present": true 6 | }, 7 | "facts": { 8 | "docker.DockerNetwork": { 9 | "object_id=nginx": [] 10 | } 11 | }, 12 | "commands": [ 13 | "docker network create nginx --ip-range 192.168.0.100/24" 14 | ] 15 | } -------------------------------------------------------------------------------- /tests/operations/docker.network/remove_network.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "network": "nginx", 4 | "present": false 5 | }, 6 | "facts": { 7 | "docker.DockerNetwork": { 8 | "object_id=nginx": [] 9 | } 10 | }, 11 | "commands": [ 12 | "docker network rm nginx" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/docker.volume/add_volume.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "volume": "nginx_volume", 4 | "present": true 5 | }, 6 | "facts": { 7 | "docker.DockerVolume": { 8 | "object_id=nginx_volume": [] 9 | } 10 | }, 11 | "commands": [ 12 | "docker volume create nginx_volume" 13 | ] 14 | } -------------------------------------------------------------------------------- /tests/operations/docker.volume/add_volume_with_driver.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "volume": "nginx_volume", 4 | "driver": "ceph", 5 | "present": true 6 | }, 7 | "facts": { 8 | "docker.DockerVolume": { 9 | "object_id=nginx_volume": [] 10 | } 11 | }, 12 | "commands": [ 13 | "docker volume create nginx_volume -d ceph" 14 | ] 15 | } -------------------------------------------------------------------------------- /tests/operations/files.block/remove_no_existing_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "require_platform": ["Darwin", "Linux"], 3 | "args": ["/home/someone/something"], 4 | "kwargs": {"present": false}, 5 | "facts": { 6 | "files.Block": { 7 | "begin=None, end=None, marker=None, path=/home/someone/something": [] 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "no remove required: markers not found" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/files.block/remove_no_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "require_platform": ["Darwin", "Linux"], 3 | "args": ["/home/someone/something"], 4 | "kwargs": {"present": false}, 5 | "facts": { 6 | "files.Block": { 7 | "begin=None, end=None, marker=None, path=/home/someone/something": null 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "no remove required: file did not exist" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/files.directory/add_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "force": true 5 | }, 6 | "facts": { 7 | "files.Directory": { 8 | "path=testdir": false 9 | } 10 | }, 11 | "commands": [ 12 | "mv testdir testdir.a-timestamp", 13 | "mkdir -p testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.directory/add_force_backup_dir.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "force": true, 5 | "force_backup_dir": "/tmp" 6 | }, 7 | "facts": { 8 | "files.Directory": { 9 | "path=testdir": false 10 | } 11 | }, 12 | "commands": [ 13 | "mv testdir /tmp/testdir.a-timestamp", 14 | "mkdir -p testdir" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/files.directory/add_force_no_backup.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "force": true, 5 | "force_backup": false 6 | }, 7 | "facts": { 8 | "files.Directory": { 9 | "path=testdir": false 10 | } 11 | }, 12 | "commands": [ 13 | "rm -rf testdir", 14 | "mkdir -p testdir" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/files.directory/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "files.Directory": { 8 | "path=testdir": { 9 | "mode": 0, 10 | "user": "testuser", 11 | "group": "testgroup" 12 | } 13 | } 14 | }, 15 | "commands": [ 16 | "rm -rf testdir" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/operations/files.directory/invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "mode": 777, 5 | "recursive": true, 6 | "group": "otheruser" 7 | }, 8 | "facts": { 9 | "files.Directory": { 10 | "path=testdir": false 11 | } 12 | }, 13 | "exception": { 14 | "name": "OperationError", 15 | "message": "testdir exists and is not a directory" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/files.directory/invalid_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["testdir", "anotherdir"]], 3 | "exception": { 4 | "name": "OperationTypeError", 5 | "message": "`path` must be a string or `os.PathLike` object" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/files.download/skip_existing.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["http://myfile"], 3 | "kwargs": { 4 | "dest": "/home/myfile" 5 | }, 6 | "facts": { 7 | "server.Date": "datetime:2015-01-01T00:00:00", 8 | "files.File": { 9 | "path=/home/myfile": {} 10 | } 11 | }, 12 | "commands": [], 13 | "noop_description": "file /home/myfile has already been downloaded" 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/files.file/add_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testfile"], 3 | "kwargs": { 4 | "force": true 5 | }, 6 | "facts": { 7 | "files.File": { 8 | "path=testfile": false 9 | } 10 | }, 11 | "commands": [ 12 | "mv testfile testfile.a-timestamp", 13 | "touch testfile" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.file/add_force_backup_dir.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testfile"], 3 | "kwargs": { 4 | "force": true, 5 | "force_backup_dir": "/tmp/somewhere" 6 | }, 7 | "facts": { 8 | "files.File": { 9 | "path=testfile": false 10 | } 11 | }, 12 | "commands": [ 13 | "mv testfile /tmp/somewhere/testfile.a-timestamp", 14 | "touch testfile" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/files.file/add_force_no_backup.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testfile"], 3 | "kwargs": { 4 | "force": true, 5 | "force_backup": false 6 | }, 7 | "facts": { 8 | "files.File": { 9 | "path=testfile": false 10 | } 11 | }, 12 | "commands": [ 13 | "rm -rf testfile", 14 | "touch testfile" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/files.file/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testfile"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "files.File": { 8 | "path=testfile": { 9 | "mode": 0, 10 | "user": "testuser", 11 | "group": "testgroup" 12 | } 13 | } 14 | }, 15 | "commands": [ 16 | "rm -f testfile" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/operations/files.file/invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testfile"], 3 | "kwargs": { 4 | "user": "testuser", 5 | "group": "testgroup", 6 | "mode": 777 7 | }, 8 | "facts": { 9 | "files.File": { 10 | "path=testfile": false 11 | } 12 | }, 13 | "exception": { 14 | "name": "OperationError", 15 | "message": "testfile exists and is not a file" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/files.file/invalid_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["testfile", "anotherfile"]], 3 | "exception": { 4 | "name": "OperationTypeError", 5 | "message": "`path` must be a string or `os.PathLike` object" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/files.flags/clear_no_flags.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/path/to/something"], 3 | "kwargs": { 4 | "flags": null, 5 | "present": false 6 | }, 7 | "facts": { 8 | }, 9 | "commands": [ 10 | ], 11 | "noop_description": "no changes requested to flags for '/path/to/something'" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/files.flags/clear_one_flag_already_clear.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": "dump", 5 | "present": false 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": [] 10 | } 11 | }, 12 | "commands": [ 13 | ], 14 | "noop_description": "'testdir' already has 'dump' clear" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/clear_one_flag_was_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": "dump", 5 | "present": false 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["dump"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags nodump testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/clear_two_flags.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": false 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["dump", "hidden", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags nodump,nohidden testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/clear_two_flags_already_clear.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": false 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["archive"] 10 | } 11 | }, 12 | "commands": [ 13 | ], 14 | "noop_description": "'testdir' already has 'dump,hidden' clear" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/clear_two_flags_first_already_clear.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": false 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["hidden", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags nohidden testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/clear_two_flags_second_already_clear.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": false 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["dump", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags nodump testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/set_no_flags.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": null, 5 | "present": true 6 | }, 7 | "facts": { 8 | }, 9 | "commands": [ 10 | ], 11 | "noop_description": "no changes requested to flags for 'testdir'" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/files.flags/set_one_flag_already_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": "dump", 5 | "present": true 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["dump", "hidden", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | ], 14 | "noop_description": "'testdir' already has 'dump' set" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/set_one_flag_not_yet_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": "dump", 5 | "present": true 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["hidden", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags dump testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/set_two_flags.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": true 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["archive"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags dump,hidden testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/set_two_flags_already_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": true 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["dump", "hidden", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | ], 14 | "noop_description": "'testdir' already has 'dump,hidden' set" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/set_two_flags_first_already_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": true 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["dump", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags hidden testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.flags/set_two_flags_second_already_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testdir"], 3 | "kwargs": { 4 | "flags": ["dump", "hidden"], 5 | "present": true 6 | }, 7 | "facts": { 8 | "files.Flags": { 9 | "path=testdir": ["hidden", "archive"] 10 | } 11 | }, 12 | "commands": [ 13 | "chflags dump testdir" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/files.get/no_local.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/home/somefile.txt", "somefile.txt"], 3 | "facts": { 4 | "files.File": { 5 | "path=/home/somefile.txt": { 6 | "mode": 500 7 | } 8 | } 9 | }, 10 | "commands": [ 11 | ["download", "/home/somefile.txt", "/somefile.txt"] 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/files.get/no_remote.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/home/somefile.txt", "somefile.txt"], 3 | "facts": { 4 | "files.File": { 5 | "path=/home/somefile.txt": null 6 | } 7 | }, 8 | "commands": [ 9 | ["download", "/home/somefile.txt", "/somefile.txt"] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/files.get/path_with_spaces.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/home/some file.txt", "somefile.txt"], 3 | "facts": { 4 | "files.File": { 5 | "path=/home/some file.txt": null 6 | } 7 | }, 8 | "commands": [ 9 | ["download", "/home/some file.txt", "/somefile.txt"] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/files.get/path_with_spaces_already_escaped.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/home/some\\ file.txt", "somefile.txt"], 3 | "facts": { 4 | "files.File": { 5 | "path=/home/some\\ file.txt": null 6 | } 7 | }, 8 | "commands": [ 9 | ["download", "/home/some\\ file.txt", "/somefile.txt"] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/files.get/pathlib_path_with_spaces.json: -------------------------------------------------------------------------------- 1 | { 2 | "require_platform": ["Darwin", "Linux"], 3 | "args": ["path:/home/some file.txt", "path:somefile.txt"], 4 | "facts": { 5 | "files.File": { 6 | "path=/home/some file.txt": null 7 | } 8 | }, 9 | "commands": [ 10 | ["download", "/home/some file.txt", "/somefile.txt"] 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/files.line/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somefile", "match_line"], 3 | "facts": { 4 | "files.FindInFile": { 5 | "interpolate_variables=False, path=somefile, pattern=^.*match_line.*$": [] 6 | } 7 | }, 8 | "commands": [ 9 | "echo match_line >> somefile" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/files.line/add_backup.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somefile", "match_line"], 3 | "kwargs": { 4 | "backup": true 5 | }, 6 | "facts": { 7 | "files.FindInFile": { 8 | "interpolate_variables=False, path=somefile, pattern=^.*match_line.*$": [] 9 | } 10 | }, 11 | "commands": [ 12 | "cp somefile somefile.a-timestamp && echo match_line >> somefile" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/files.line/add_with_quote.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somefile", "match line"], 3 | "facts": { 4 | "files.FindInFile": { 5 | "interpolate_variables=False, path=somefile, pattern=^.*match line.*$": [] 6 | } 7 | }, 8 | "commands": [ 9 | "echo 'match line' >> somefile" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/files.link/add_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testlink"], 3 | "kwargs": { 4 | "target": "/etc/init.d/nginx", 5 | "force": true 6 | }, 7 | "facts": { 8 | "files.Link": { 9 | "path=testlink": false 10 | } 11 | }, 12 | "commands": [ 13 | "mv testlink testlink.a-timestamp", 14 | "ln -s /etc/init.d/nginx testlink" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/files.link/add_force_no_backup.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testlink"], 3 | "kwargs": { 4 | "target": "/etc/init.d/nginx", 5 | "force": true, 6 | "force_backup": false 7 | }, 8 | "facts": { 9 | "files.Link": { 10 | "path=testlink": false 11 | } 12 | }, 13 | "commands": [ 14 | "rm -rf testlink", 15 | "ln -s /etc/init.d/nginx testlink" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/files.link/add_no_target.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testlink"], 3 | "kwargs": { 4 | "user": "testuser", 5 | "group": "testgroup" 6 | }, 7 | "facts": { 8 | "files.Link": { 9 | "path=testlink": null 10 | } 11 | }, 12 | "exception": { 13 | "name": "OperationError", 14 | "message": "If present is True target must be provided" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/files.link/invalid_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["testlink", "anotherlink"]], 3 | "exception": { 4 | "name": "OperationTypeError", 5 | "message": "`path` must be a string or `os.PathLike` object" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/files.put/no_local.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somefile.txt", "/home/somefile.txt"], 3 | "exception": { 4 | "names": ["OSError", "IOError"], 5 | "message": "No such file: /somefile.txt" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/files.replace/no_match.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["filename", "match", "replace"], 3 | "facts": { 4 | "files.FindInFile": { 5 | "interpolate_variables=False, path=filename, pattern=match": [] 6 | } 7 | }, 8 | "commands": [], 9 | "noop_description": "string \"match\" does not exist in filename" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/flatpak.packages/install_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "packages": ["org.videolan.VLC"] 4 | }, 5 | "facts": { 6 | "flatpak.FlatpakPackage": {}, 7 | "flatpak.FlatpakPackages": [] 8 | }, 9 | "commands": ["flatpak install --noninteractive org.videolan.VLC"] 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/flatpak.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "packages": ["org.videolan.VLC", "tv.kodi.Kodi"], 4 | "present": false 5 | }, 6 | "facts": { 7 | "flatpak.FlatpakPackage": {}, 8 | "flatpak.FlatpakPackages": ["org.videolan.VLC"] 9 | }, 10 | "commands": ["flatpak uninstall --noninteractive org.videolan.VLC"], 11 | "noop_description": "flatpak package tv.kodi.Kodi is not installed" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/freebsd.freebsd_update.update/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands" : [ 3 | "PAGER=cat freebsd-update --not-running-from-cron fetch install" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.autoremove/autoremove-with-jail.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "jail" : "nginx" 4 | }, 5 | "commands" : [ 6 | "pkg -j nginx autoremove -y" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.autoremove/autoremove.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands" : [ 3 | "pkg autoremove -y" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.clean/clean-all-with-jail.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "jail" : "redis", 4 | "all_pkg" : true 5 | }, 6 | "commands" : [ 7 | "pkg -j redis clean -y -a" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.clean/clean-all.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "all_pkg" : true 4 | }, 5 | "commands" : [ 6 | "pkg clean -y -a" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.clean/clean-with-jail.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "jail" : "redis" 4 | }, 5 | "commands" : [ 6 | "pkg -j redis clean -y" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.clean/clean.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands" : [ 3 | "pkg clean -y" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.install/install-with-custom-repo.json: -------------------------------------------------------------------------------- 1 | { 2 | "args" : ["screen"], 3 | "kwargs" : { 4 | "reponame" : "custom" 5 | }, 6 | "facts" : { 7 | "freebsd.PkgPackage" : { 8 | "jail=None, package=screen" : null 9 | } 10 | }, 11 | "commands" : [ 12 | "pkg install -y -r custom -- screen" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.install/install-with-jail-and-custom-repo.json: -------------------------------------------------------------------------------- 1 | { 2 | "args" : ["screen"], 3 | "kwargs" : { 4 | "jail" : "nginx", 5 | "reponame" : "custom" 6 | }, 7 | "facts" : { 8 | "freebsd.PkgPackage" : { 9 | "jail=nginx, package=screen" : null 10 | } 11 | }, 12 | "commands" : [ 13 | "pkg -j nginx install -y -r custom -- screen" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.install/install-with-jail.json: -------------------------------------------------------------------------------- 1 | { 2 | "args" : ["screen"], 3 | "kwargs" : { 4 | "jail" : "nginx" 5 | }, 6 | "facts" : { 7 | "freebsd.PkgPackage" : { 8 | "jail=nginx, package=screen" : null 9 | } 10 | }, 11 | "commands" : [ 12 | "pkg -j nginx install -y -- screen" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.install/install.json: -------------------------------------------------------------------------------- 1 | { 2 | "args" : ["screen"], 3 | "facts" : { 4 | "freebsd.PkgPackage" : { 5 | "jail=None, package=screen" : null 6 | } 7 | }, 8 | "commands" : [ 9 | "pkg install -y -- screen" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.remove/remove-with-jail.json: -------------------------------------------------------------------------------- 1 | { 2 | "args" : ["screen"], 3 | "kwargs" : { 4 | "jail" : "nginx" 5 | }, 6 | "facts" : { 7 | "freebsd.PkgPackage" : { 8 | "jail=nginx, package=screen" : null 9 | } 10 | }, 11 | "commands" : [], 12 | "noop_description": "Package 'screen' cannot be found" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.remove/remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args" : ["screen"], 3 | "facts" : { 4 | "freebsd.PkgPackage" : { 5 | "jail=None, package=screen" : null 6 | } 7 | }, 8 | "commands" : [], 9 | "noop_description": "Package 'screen' cannot be found" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.update/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands": [ 3 | "pkg update" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/operations/freebsd.pkg.upgrade/upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands": [ 3 | "pkg upgrade -y" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/operations/freebsd.sysrc.sysrc/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "parameter" : "kld_list", 4 | "value" : "radeonkms", 5 | "command" : "add" 6 | }, 7 | "facts" : { 8 | "freebsd.Sysrc" : { 9 | "jail=None, parameter=kld_list" : null 10 | } 11 | }, 12 | "commands" : [ 13 | "sysrc -i -- kld_list+=radeonkms" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/freebsd.sysrc.sysrc/del.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "parameter" : "memcached_enable", 4 | "value" : null, 5 | "command" : "del" 6 | }, 7 | "facts" : { 8 | "freebsd.Sysrc" : { 9 | "jail=None, parameter=memcached_enable" : "YES" 10 | } 11 | }, 12 | "commands" : [ 13 | "sysrc -i -x -- memcached_enable=None" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/freebsd.sysrc.sysrc/set.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "parameter" : "memcached_enable", 4 | "value" : "YES", 5 | "command" : "set" 6 | }, 7 | "facts" : { 8 | "freebsd.Sysrc" : { 9 | "jail=None, parameter=memcached_enable" : null 10 | } 11 | }, 12 | "commands" : [ 13 | "sysrc -i -- memcached_enable=YES" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/freebsd.sysrc.sysrc/sub.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs" : { 3 | "parameter" : "kld_list", 4 | "value" : "radeonkms", 5 | "command" : "sub" 6 | }, 7 | "facts" : { 8 | "freebsd.Sysrc" : { 9 | "jail=None, parameter=kld_list" : "radeonkms" 10 | } 11 | }, 12 | "commands" : [ 13 | "sysrc -i -- kld_list-=radeonkms" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/gem.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["rubyenv"], 3 | "facts": { 4 | "gem.GemPackages": {} 5 | }, 6 | "commands": [ 7 | "gem install rubyenv" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/gem.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["rubyenv"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "gem.GemPackages": { 8 | "rubyenv": true 9 | } 10 | }, 11 | "commands": [ 12 | "gem uninstall rubyenv" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/git.config/add_existing_multi_value.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "kwargs": { 4 | "multi_value": true 5 | }, 6 | "facts": { 7 | "git.GitConfig": { 8 | "repo=None, system=False": { 9 | "key": ["value"] 10 | } 11 | } 12 | }, 13 | "commands": [], 14 | "noop_description": "git config key is set to value" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/git.config/add_first_multi_value.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "kwargs": { 4 | "multi_value": true 5 | }, 6 | "facts": { 7 | "git.GitConfig": { 8 | "repo=None, system=False": {} 9 | } 10 | }, 11 | "commands": [ 12 | "git config --global --add key \"value\"" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/git.config/add_second_multi_value.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "another_value"], 3 | "kwargs": { 4 | "multi_value": true 5 | }, 6 | "facts": { 7 | "git.GitConfig": { 8 | "repo=None, system=False": { 9 | "key": ["value"] 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "git config --global --add key \"another_value\"" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/git.config/edit_global.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "facts": { 4 | "git.GitConfig": { 5 | "repo=None, system=False": { 6 | "key": ["wrongvalue"] 7 | } 8 | } 9 | }, 10 | "commands": [ 11 | "git config --global key \"value\"" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/git.config/edit_system.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "kwargs": { 4 | "system": true 5 | }, 6 | "facts": { 7 | "git.GitConfig": { 8 | "repo=None, system=True": { 9 | "key": ["wrongvalue"] 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "git config --system key \"value\"" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/git.config/set_existing_global.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "facts": { 4 | "git.GitConfig": { 5 | "repo=None, system=False": { 6 | "key": ["value"] 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "git config key is set to value" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/git.config/set_existing_system.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "kwargs": { 4 | "system": true 5 | }, 6 | "facts": { 7 | "git.GitConfig": { 8 | "repo=None, system=True": { 9 | "key": ["value"] 10 | } 11 | } 12 | }, 13 | "commands": [], 14 | "noop_description": "git config key is set to value" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/git.config/set_global.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "facts": { 4 | "git.GitConfig": { 5 | "repo=None, system=False": {} 6 | } 7 | }, 8 | "commands": [ 9 | "git config --global key \"value\"" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/git.config/set_system.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["key", "value"], 3 | "kwargs": { 4 | "system": true 5 | }, 6 | "facts": { 7 | "git.GitConfig": { 8 | "repo=None, system=True": {} 9 | } 10 | }, 11 | "commands": [ 12 | "git config --system key \"value\"" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/git.worktree/remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/home/myworktree"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "files.Directory": { 8 | "path=/home/myworktree": { 9 | "mode": 0 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "cd /home/myworktree && git worktree remove ." 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/git.worktree/remove_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/home/myworktree"], 3 | "kwargs": { 4 | "present": false, 5 | "force": true 6 | }, 7 | "facts": { 8 | "files.Directory": { 9 | "path=/home/myworktree": { 10 | "mode": 0 11 | } 12 | } 13 | }, 14 | "commands": [ 15 | "cd /home/myworktree && git worktree remove . --force" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/iptables.chain/add_chain.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["MYCHAIN"], 3 | "kwargs": { 4 | "policy": "DROP" 5 | }, 6 | "facts": { 7 | "iptables.IptablesChains": { 8 | "table=filter": {} 9 | } 10 | }, 11 | "commands": [ 12 | "iptables -t filter -N MYCHAIN", 13 | "iptables -t filter -P MYCHAIN DROP" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/iptables.chain/delete_chain.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["MYCHAIN"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "iptables.IptablesChains": { 8 | "table=filter": { 9 | "MYCHAIN": "ACCEPT" 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "iptables -t filter -X MYCHAIN" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/iptables.chain/delete_chain_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["MYCHAIN"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "iptables.IptablesChains": { 8 | "table=filter": {} 9 | } 10 | }, 11 | "commands": [], 12 | "noop_description": "iptables chain MYCHAIN does not exist" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/iptables.chain/edit_chain.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["MYCHAIN"], 3 | "kwargs": { 4 | "policy": "DROP" 5 | }, 6 | "facts": { 7 | "iptables.IptablesChains": { 8 | "table=filter": { 9 | "MYCHAIN": "ACCEPT" 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "iptables -t filter -P MYCHAIN DROP" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/add_log_rule.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["INPUT", "LOG"], 3 | "kwargs": { 4 | "log_prefix": "log-prefix" 5 | }, 6 | "facts": { 7 | "iptables.IptablesRules": { 8 | "table=filter": [] 9 | } 10 | }, 11 | "commands": [ 12 | "iptables -t filter -A INPUT -j LOG --log-prefix log-prefix" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/add_to_ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["PREROUTING", "REDIRECT"], 3 | "kwargs": { 4 | "table": "nat", 5 | "to_ports": 8000 6 | }, 7 | "facts": { 8 | "iptables.IptablesRules": { 9 | "table=nat": [] 10 | } 11 | }, 12 | "commands": [ 13 | "iptables -t nat -A PREROUTING -j REDIRECT --to-ports 8000" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/add_to_source.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["PREROUTING", "SNAT"], 3 | "kwargs": { 4 | "table": "nat", 5 | "to_source": "10.0.0.0:8000" 6 | }, 7 | "facts": { 8 | "iptables.IptablesRules": { 9 | "table=nat": [] 10 | } 11 | }, 12 | "commands": [ 13 | "iptables -t nat -A PREROUTING -j SNAT --to-source 10.0.0.0:8000" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/already_absent.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["PREROUTING", "DNAT"], 3 | "kwargs": { 4 | "to_destination": "10.10.10.10", 5 | "present": false, 6 | "table": "nat" 7 | }, 8 | "facts": { 9 | "iptables.IptablesRules": { 10 | "table=nat": [] 11 | } 12 | }, 13 | "commands": [], 14 | "noop_description": "iptables PREROUTING rule does not exists" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/invalid_destination_port.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["PREROUTING", "ACCEPT"], 3 | "kwargs": { 4 | "destination_port": 8080 5 | }, 6 | "exception": { 7 | "name": "OperationError", 8 | "message": "iptables cannot filter by destination_port/source_port without a protocol" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/invalid_log_prefix.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["INPUT", "NOT_LOG"], 3 | "kwargs": { 4 | "log_prefix": "log-prefix" 5 | }, 6 | "exception": { 7 | "name": "OperationError", 8 | "message": "iptables only supports log_prefix with the LOG jump (jump=NOT_LOG)" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/invalid_source_destination.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["PREROUTING", "SNAT"], 3 | "kwargs": { 4 | "to_source": "8.8.8.8" 5 | }, 6 | "exception": { 7 | "name": "OperationError", 8 | "message": "iptables only supports to_source on the nat table and the SNAT jump (table=filter, jump=SNAT)" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/invalid_to_destination.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["PREROUTING", "DNAT"], 3 | "kwargs": { 4 | "to_destination": "8.8.8.8" 5 | }, 6 | "exception": { 7 | "name": "OperationError", 8 | "message": "iptables only supports to_destination on the nat table and the DNAT jump (table=filter, jump=DNAT)" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/iptables.rule/invalid_to_ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["PREROUTING", "REDIRECT"], 3 | "kwargs": { 4 | "to_ports": "8.8.8.8" 5 | }, 6 | "exception": { 7 | "name": "OperationError", 8 | "message": "iptables only supports to_ports on the nat table and the REDIRECT jump (table=filter, jump=REDIRECT)" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/launchd.service/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["com.fizzadar.thing"], 3 | "facts": { 4 | "launchd.LaunchdStatus": { 5 | "com.fizzadar.thing": false 6 | } 7 | }, 8 | "commands": [ 9 | "launchctl start com.fizzadar.thing" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/launchd.service/start_running.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["com.fizzadar.thing"], 3 | "facts": { 4 | "launchd.LaunchdStatus": { 5 | "com.fizzadar.thing": true 6 | } 7 | }, 8 | "commands": [], 9 | "noop_description": "service com.fizzadar.thing is running" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/launchd.service/stop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["com.fizzadar.thing"], 3 | "kwargs": { 4 | "running": false 5 | }, 6 | "facts": { 7 | "launchd.LaunchdStatus": { 8 | "com.fizzadar.thing": true 9 | } 10 | }, 11 | "commands": [ 12 | "launchctl stop com.fizzadar.thing" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/lxd.container/add_container.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "id": "container1", 4 | "image": "ubuntu:16.04" 5 | }, 6 | "facts": { 7 | "lxd.LxdContainers": [] 8 | }, 9 | "commands": [ 10 | "lxc launch ubuntu:16.04 container1 < /dev/null" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/lxd.container/already_present.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "id": "container1", 4 | "image": "ubuntu:16.04" 5 | }, 6 | "facts": { 7 | "lxd.LxdContainers": [ 8 | { 9 | "name": "container1", 10 | "status": "Running" 11 | } 12 | ] 13 | }, 14 | "commands": [], 15 | "noop_description": "container container1 exists" 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/mysql.database/add_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somedb"], 3 | "facts": { 4 | "mysql.MysqlDatabases": { 5 | "mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None": { 6 | "somedb": {} 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "mysql database somedb exists" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/mysql.database/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somedb"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "mysql.MysqlDatabases": { 8 | "mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None": { 9 | "somedb": {} 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "mysql -Be 'DROP DATABASE `somedb`'" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/mysql.database/delete_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somedb"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "mysql.MysqlDatabases": { 8 | "mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None": {} 9 | } 10 | }, 11 | "commands": [], 12 | "noop_description": "mysql database somedb does not exist" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/mysql.load/load.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somefile"], 3 | "kwargs": { 4 | "database": "somedb", 5 | "mysql_user": "root" 6 | }, 7 | "commands": [ 8 | "mysql somedb -u\"root\" < somefile" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/mysql.load/load_space.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["some file"], 3 | "kwargs": { 4 | "database": "somedb", 5 | "mysql_user": "root" 6 | }, 7 | "commands": [ 8 | "mysql somedb -u\"root\" < 'some file'" 9 | ], 10 | "idempotent": false 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/mysql.privileges/remove_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser", []], 3 | "facts": { 4 | "mysql.MysqlUserGrants": { 5 | "hostname=localhost, mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None, user=someuser": { 6 | "*.*": ["set:"] 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "mysql privileges are already correct" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/mysql.sql/execute.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["SELECT 1"], 3 | "commands": [ 4 | "mysql -Be 'SELECT 1'" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "user_hostname": "localwhat" 5 | }, 6 | "facts": { 7 | "mysql.MysqlUsers": { 8 | "mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None": {} 9 | } 10 | }, 11 | "commands": [ 12 | "mysql -Be 'CREATE USER \"someuser\"@\"localwhat\"'" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/add_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "facts": { 4 | "mysql.MysqlUsers": { 5 | "mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None": { 6 | "someuser@localhost": {} 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "mysql user someuser@localhost exists" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/add_ssl.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "require": "SSL" 5 | }, 6 | "facts": { 7 | "mysql.MysqlUsers": { 8 | "mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None": {} 9 | } 10 | }, 11 | "commands": [ 12 | "mysql -Be 'CREATE USER \"someuser\"@\"localhost\" REQUIRE SSL'" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/invalid_require_cipher.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "require": "SSL", 5 | "require_cipher": "a-cipher" 6 | }, 7 | "exception": { 8 | "name": "OperationError", 9 | "message": "Cannot set `require_cipher` if `require` is not \"X509\"" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/invalid_require_issuer.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "require": "SSL", 5 | "require_issuer": "a-issuer" 6 | }, 7 | "exception": { 8 | "name": "OperationError", 9 | "message": "Cannot set `require_issuer` if `require` is not \"X509\"" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/invalid_require_subject.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "require": "SSL", 5 | "require_subject": "a-subject" 6 | }, 7 | "exception": { 8 | "name": "OperationError", 9 | "message": "Cannot set `require_subject` if `require` is not \"X509\"" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/invalid_require_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "require": "invalid" 5 | }, 6 | "exception": { 7 | "name": "OperationError", 8 | "message": "Invalid `require` value, must be: \"SSL\" or \"X509\"" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/mysql.user/remove_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "mysql.MysqlUsers": { 8 | "mysql_host=None, mysql_password=None, mysql_port=None, mysql_user=None": {} 9 | } 10 | }, 11 | "commands": [], 12 | "noop_description": "mysql user someuser@localhost does not exist" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/npm.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["git@1.1", "react", "test@1.1"]], 3 | "facts": { 4 | "npm.NpmPackages": { 5 | "directory=None": { 6 | "git": ["1.0"], 7 | "test": ["1.1"] 8 | } 9 | } 10 | }, 11 | "commands": [ 12 | "npm install -g git@1.1 react" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/openrc.service/running_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "facts": { 4 | "openrc.OpenrcStatus": { 5 | "runlevel=default": { 6 | "nginx": true 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "service nginx is running" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/openrc.service/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "facts": { 4 | "openrc.OpenrcStatus": { 5 | "runlevel=default": { 6 | "nginx": false 7 | } 8 | } 9 | }, 10 | "commands": [ 11 | "rc-service nginx start" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/openrc.service/stop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "kwargs": { 4 | "running": false 5 | }, 6 | "facts": { 7 | "openrc.OpenrcStatus": { 8 | "runlevel=default": { 9 | "nginx": true 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "rc-service nginx stop" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/openrc.service/stopped_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "kwargs": { 4 | "running": false 5 | }, 6 | "facts": { 7 | "openrc.OpenrcStatus": { 8 | "runlevel=default": { 9 | "nginx": false 10 | } 11 | } 12 | }, 13 | "commands": [], 14 | "noop_description": "service nginx is stopped" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/add_existing_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": { 4 | "update": false 5 | }, 6 | "facts": { 7 | "opkg.OpkgPackages": {"curl": ["7.66.0-2"]} 8 | }, 9 | "commands": [ 10 | ], 11 | "noop_description": "package curl is installed (7.66.0-2)" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/add_multiple_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args":[["curl", "wget"]], 3 | "kwargs": { 4 | "update": false 5 | }, 6 | "facts": { 7 | "opkg.OpkgPackages": {} 8 | }, 9 | "commands": [ 10 | "opkg install curl wget" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/add_one_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": { 4 | "update": false 5 | }, 6 | "facts": { 7 | "opkg.OpkgPackages": {} 8 | }, 9 | "commands": [ 10 | "opkg install curl" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/add_with_unallowed_pinning.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl=7.66.0-2"], 3 | "facts": { 4 | "opkg.OpkgPackages": {} 5 | }, 6 | "commands": [ ], 7 | "exception": { 8 | "name":"ValueError", 9 | "message": "opkg does not support version pinning but found for: 'curl'" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/list_of_nulls_package_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["", "", ""], 3 | "facts": { 4 | "opkg.OpkgPackages": {} 5 | }, 6 | "commands": [], 7 | "noop_description": "empty or invalid package list provided to opkg.packages", 8 | "logs": "foo" 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/null_package_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "facts": { 4 | "opkg.OpkgPackages": {} 5 | }, 6 | "commands": [], 7 | "noop_description": "empty or invalid package list provided to opkg.packages", 8 | "logs": "foo" 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/remove_existing_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": { 4 | "present": false, 5 | "update": false 6 | }, 7 | "facts": { 8 | "opkg.OpkgPackages": {"curl": ["7.66.0-2"]} 9 | }, 10 | "commands": [ 11 | "opkg remove curl" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/remove_existing_package_and_require_update.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": { 4 | "present": false, 5 | "update": true 6 | }, 7 | "facts": { 8 | "opkg.OpkgPackages": {"curl": ["7.66.0-2"]} 9 | }, 10 | "commands": [ 11 | "opkg update", 12 | "opkg remove curl" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/remove_not_existing_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": { 4 | "present": false, 5 | "update": false 6 | }, 7 | "facts": { 8 | "opkg.OpkgPackages": {} 9 | }, 10 | "commands": [ 11 | ], 12 | "noop_description": "package curl is not installed" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/opkg.packages/update_then_add_one.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": {"update": true}, 4 | "facts": { 5 | "opkg.OpkgPackages": {} 6 | }, 7 | "commands": [ 8 | "opkg update", 9 | "opkg install curl" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/opkg.update/first_update.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "facts": { 4 | "opkg.OpkgPackages": {} 5 | }, 6 | "commands": [ 7 | "opkg update" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/pacman.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["curl", "xorg-fonts"]], 3 | "facts": { 4 | "pacman.PacmanUnpackGroup": { 5 | "package=curl": ["curl"], 6 | "package=xorg-fonts": ["xorg-font-util", "xorg-fonts-encodings"] 7 | }, 8 | "pacman.PacmanPackages": {} 9 | }, 10 | "commands": [ 11 | "pacman --noconfirm -S curl xorg-fonts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/pacman.packages/add_packages_group_expand.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["xorg-fonts"]], 3 | "facts": { 4 | "pacman.PacmanUnpackGroup": { 5 | "package=xorg-fonts": ["xorg-font-util", "xorg-font-encodings"] 6 | }, 7 | "pacman.PacmanPackages": {} 8 | }, 9 | "commands": [ 10 | "pacman --noconfirm -S xorg-fonts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/pip.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["pyinfra==1.1", "pytask", "test==1.1", "another>1"]], 3 | "facts": { 4 | "pip.PipPackages": { 5 | "pip=pip": { 6 | "pyinfra": ["1.0"], 7 | "test": ["1.1"] 8 | } 9 | } 10 | }, 11 | "commands": [ 12 | "pip install pyinfra==1.1 pytask 'another>1'" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/pip.packages/add_packages_case_insensitive.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["pyinfra==1.1", "PyTask", "test==1.1", "ANoTHEr>1"]], 3 | "facts": { 4 | "pip.PipPackages": { 5 | "pip=pip": { 6 | "pyinfra": ["1.0"], 7 | "test": ["1.1"] 8 | } 9 | } 10 | }, 11 | "commands": [ 12 | "pip install pyinfra==1.1 pytask 'another>1'" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/pip.packages/install_latest_requirements.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "latest": true, 4 | "requirements": "requirements.txt" 5 | }, 6 | "facts": {}, 7 | "commands": [ 8 | "pip install --upgrade -r requirements.txt" 9 | ], 10 | "idempotent": false, 11 | "disable_idempotent_warning_reason": "pip package requirements are always executed" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/pip.packages/install_requirements.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "requirements": "requirements.txt" 4 | }, 5 | "facts": {}, 6 | "commands": [ 7 | "pip install -r requirements.txt" 8 | ], 9 | "idempotent": false, 10 | "disable_idempotent_warning_reason": "pip package requirements are always executed" 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/pip.packages/uninstall_requirements.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "requirements": "requirements.txt", 4 | "present": false 5 | }, 6 | "facts": {}, 7 | "commands": [ 8 | "pip uninstall --yes -r requirements.txt" 9 | ], 10 | "idempotent": false, 11 | "disable_idempotent_warning_reason": "pip package requirements are always executed" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/pip.packages/use_pip3.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["test"]], 3 | "kwargs": { 4 | "pip": "pip3" 5 | }, 6 | "facts": { 7 | "pip.PipPackages": { 8 | "pip=pip3": {} 9 | } 10 | }, 11 | "commands": [ 12 | "pip3 install test" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/pip.venv/add_virtualenv.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "path": "/some/virtualenv", 4 | "always_copy": true 5 | }, 6 | "facts": { 7 | "files.File": { 8 | "path=/some/virtualenv/bin/activate": null 9 | } 10 | }, 11 | "commands": [ 12 | "python -m venv --copies /some/virtualenv" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/pip.virtualenv/add_virtualenv.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "path": "/some/virtualenv" 4 | }, 5 | "facts": { 6 | "files.File": { 7 | "path=/some/virtualenv/bin/activate": null 8 | } 9 | }, 10 | "commands": [ 11 | "virtualenv /some/virtualenv" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/pip.virtualenv/add_virtualenv_py3.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "path": "/some/virtualenv", 4 | "python": "python3" 5 | }, 6 | "facts": { 7 | "files.File": { 8 | "path=/some/virtualenv/bin/activate": null 9 | } 10 | }, 11 | "commands": [ 12 | "virtualenv -p python3 /some/virtualenv" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/pip.virtualenv/already_present.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "path": "/some/virtualenv" 4 | }, 5 | "facts": { 6 | "files.File": { 7 | "path=/some/virtualenv/bin/activate": true 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "virtualenv /some/virtualenv exists" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/pip.virtualenv/present_empty_directory.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "path": "/some/virtualenv" 4 | }, 5 | "facts": { 6 | "files.File": { 7 | "path=/some/virtualenv/bin/activate": null 8 | }, 9 | "files.Directory": { 10 | "path=/some/virtualenv": true 11 | } 12 | }, 13 | "commands": [ 14 | "virtualenv /some/virtualenv" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/pip.virtualenv/use_stdlib_venv.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "path": "/some/virtualenv", 4 | "venv": true, 5 | "always_copy": true 6 | }, 7 | "facts": { 8 | "files.File": { 9 | "path=/some/virtualenv/bin/activate": null 10 | } 11 | }, 12 | "commands": [ 13 | "python -m venv --copies /some/virtualenv" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/pip.virtualenv/use_stdlib_venv_py3.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "path": "/some/virtualenv", 4 | "python": "python3", 5 | "venv": true 6 | }, 7 | "facts": { 8 | "files.File": { 9 | "path=/some/virtualenv/bin/activate": null 10 | } 11 | }, 12 | "commands": [ 13 | "python3 -m venv /some/virtualenv" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/pipx.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["copier==0.9.1", "invoke", "ensurepath"]], 3 | "facts": { 4 | "pipx.PipxPackages": {"ensurepath": ["0.1.1"]} 5 | }, 6 | "commands": [ 7 | "pipx install copier==0.9.1", 8 | "pipx install invoke" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/pipx.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["invoke", "copier"]], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "pipx.PipxPackages": { 8 | "copier": ["9.0.1"], 9 | "invoke": ["2.2.0"] 10 | } 11 | }, 12 | "commands": [ 13 | "pipx uninstall invoke", 14 | "pipx uninstall copier" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/pipx.upgrade_all/upgrade_all.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "facts": {}, 4 | "commands": [ 5 | "pipx upgrade-all" 6 | ], 7 | "idempotent": false, 8 | "disable_idempotent_warning_reason": "package upgrades are always executed" 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/pkgin.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "facts": { 4 | "pkgin.PkginPackages": {} 5 | }, 6 | "commands": [ 7 | "pkgin -y install curl" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/pkgin.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["curl", "i-dont-exist"]], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "pkgin.PkginPackages": { 8 | "curl": "1" 9 | } 10 | }, 11 | "commands": [ 12 | "pkgin -y remove curl" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/pkgin.packages/upgrade_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "kwargs": { 4 | "latest": true 5 | }, 6 | "facts": { 7 | "pkgin.PkginPackages": {} 8 | }, 9 | "commands": [ 10 | "pkgin -y install curl" 11 | ], 12 | "idempotent": false, 13 | "disable_idempotent_warning_reason": "package upgrades are always executed" 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/postgresql.database/add_database.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somedb"], 3 | "facts" :{ 4 | "postgres.PostgresDatabases": { 5 | "psql_database=None, psql_host=None, psql_password=None, psql_port=None, psql_user=None": {} 6 | } 7 | }, 8 | "commands": [ 9 | "psql -Ac 'CREATE DATABASE \"somedb\"'" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/postgresql.database/remove_database_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somedb"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts" :{ 7 | "postgres.PostgresDatabases": { 8 | "psql_database=None, psql_host=None, psql_password=None, psql_port=None, psql_user=None": {} 9 | } 10 | }, 11 | "commands": [], 12 | "noop_description": "postgresql database somedb does not exist" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/postgresql.role/role_remove_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testuser"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "postgres.PostgresRoles": { 8 | "psql_database=None, psql_host=None, psql_password=None, psql_port=None, psql_user=None": {} 9 | } 10 | }, 11 | "commands": [], 12 | "noop_description": "postgresql role testuser does not exist" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/postgresql.role/user_add_no_login.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testuser"], 3 | "kwargs": { 4 | "login": false 5 | }, 6 | "facts": { 7 | "postgres.PostgresRoles": { 8 | "psql_database=None, psql_host=None, psql_password=None, psql_port=None, psql_user=None": {} 9 | } 10 | }, 11 | "commands": [ 12 | "psql -Ac 'CREATE ROLE \"testuser\"'" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/postgresql.role/user_add_super.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testuser"], 3 | "kwargs": { 4 | "superuser": true 5 | }, 6 | "facts": { 7 | "postgres.PostgresRoles": { 8 | "psql_database=None, psql_host=None, psql_password=None, psql_port=None, psql_user=None": {} 9 | } 10 | }, 11 | "commands": [ 12 | "psql -Ac 'CREATE ROLE \"testuser\" LOGIN SUPERUSER'" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/postgresql.role/user_remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["testuser"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "postgres.PostgresRoles": { 8 | "psql_database=None, psql_host=None, psql_password=None, psql_port=None, psql_user=None": { 9 | "testuser": {} 10 | } 11 | } 12 | }, 13 | "commands": ["psql -Ac 'DROP ROLE \"testuser\"'"] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/postgresql.sql/execute.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["SELECT 1"], 3 | "kwargs": { 4 | "psql_user": "postgres", 5 | "psql_host": "127.0.0.1", 6 | "psql_port": 5432 7 | }, 8 | "commands": [ 9 | "psql -U postgres -h 127.0.0.1 -p 5432 -Ac 'SELECT 1'" 10 | ], 11 | "idempotent": false 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/puppet.agent/run_agent.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "server": "my-server.net", 4 | "port": 3006 5 | }, 6 | "commands": [ 7 | "puppet agent -t --server=my-server.net --masterport=3006" 8 | ], 9 | "idempotent": false 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/python.call/call_func.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["__func__", "arg1", "arg2"], 3 | "kwargs": { 4 | "hello": "world" 5 | }, 6 | "commands": [ 7 | ["__func__", ["arg1", "arg2"], {"hello": "world"}] 8 | ], 9 | "idempotent": false 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/python.raise_exception/call_func.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["__func__", "arg1", "arg2"], 3 | "commands": [ 4 | ["raise_exc", ["arg1", "arg2"], {}] 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/selinux.boolean/bad_value.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["some_boolean", "really-off"], 3 | "kwargs": { 4 | "persistent": true 5 | }, 6 | "exception": { 7 | "name": "OperationValueError", 8 | "message": "Invalid value 'really-off' for boolean operation" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/selinux.boolean/change_not_persistent.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["some_boolean", "off"], 3 | "kwargs": { 4 | }, 5 | "facts": { 6 | "selinux.SEBoolean": { 7 | "boolean=some_boolean": "on" 8 | } 9 | }, 10 | "commands": [ 11 | "setsebool some_boolean off" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/selinux.boolean/change_persistent.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["some_boolean", "on"], 3 | "kwargs": { 4 | "persistent":true 5 | }, 6 | "facts": { 7 | "selinux.SEBoolean": { 8 | "boolean=some_boolean": "off" 9 | } 10 | }, 11 | "commands": [ 12 | "setsebool -P some_boolean on" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/selinux.boolean/no_change.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["some_boolean", "on"], 3 | "kwargs": { 4 | "persistent":true 5 | }, 6 | "facts": { 7 | "selinux.SEBoolean": { 8 | "boolean=some_boolean": "on" 9 | } 10 | }, 11 | "commands": [ 12 | ], 13 | "noop_description": "boolean 'some_boolean' already had the value 'on'" 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/selinux.file_context/change.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/etc", "var_t"], 3 | "kwargs": { 4 | }, 5 | "facts": { 6 | "selinux.FileContext": { 7 | "path=/etc": {"type": "etc_t"} 8 | } 9 | }, 10 | "commands": [ 11 | "chcon -t var_t /etc" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/selinux.file_context/no_change.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/foo/bar", "httpd_sys_content_t"], 3 | "kwargs": { 4 | }, 5 | "facts": { 6 | "selinux.FileContext": { 7 | "path=/foo/bar": {"type": "httpd_sys_content_t"} 8 | } 9 | }, 10 | "commands": [ 11 | ], 12 | "noop_description": "file_context: '/foo/bar' already had type 'httpd_sys_content_t'" 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/selinux.file_context_mapping/add_None.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/web(/.*)?"], 3 | "kwargs": { 4 | "se_type": null, 5 | "present": true 6 | }, 7 | "exception": { 8 | "name": "ValueError", 9 | "message": "se_type must have a valid value if present is set" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/selinux.file_context_mapping/add_none_existeing.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/web(/.*)?"], 3 | "kwargs": { 4 | "se_type": "httpd_sys_content_t", 5 | "present":true 6 | }, 7 | "facts": { 8 | "selinux.FileContextMapping": { 9 | "target=/web(/.*)?": {} 10 | } 11 | }, 12 | "commands": [ 13 | "semanage fcontext -a -t httpd_sys_content_t '/web(/.*)?'" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/selinux.file_context_mapping/delete_existing.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/web(/.*)?"], 3 | "kwargs": { 4 | "present":false 5 | }, 6 | "facts": { 7 | "selinux.FileContextMapping": { 8 | "target=/web(/.*)?": {"type": "httpd_sys_content_t"} 9 | } 10 | }, 11 | "commands": [ 12 | "semanage fcontext -d '/web(/.*)?'" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/selinux.file_context_mapping/delete_none_existing.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/web(/.*)?"], 3 | "kwargs": { 4 | "present":false 5 | }, 6 | "facts": { 7 | "selinux.FileContextMapping": { 8 | "target=/web(/.*)?": {} 9 | } 10 | }, 11 | "commands": [ 12 | ], 13 | "noop_description": "no existing mapping for '/web(/.*)?'" 14 | 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/selinux.port/add_None.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["tcp", 22], 3 | "kwargs": { 4 | "present": true 5 | }, 6 | "exception": { 7 | "name": "ValueError", 8 | "message": "se_type must have a valid value if present is set" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/selinux.port/add_not_existing.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["tcp", 22, "ssh_port_t"], 3 | "kwargs": { 4 | "present":true 5 | }, 6 | "facts": { 7 | "selinux.SEPorts": { 8 | "tcp": {"22": ""} 9 | }, 10 | "server.Which": { 11 | "command=sepolicy": null 12 | } 13 | }, 14 | "commands": [ 15 | "semanage port -a -t ssh_port_t -p tcp 22" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/selinux.port/add_not_existing_protocol.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["tcp", 22, "ssh_port_t"], 3 | "kwargs": { 4 | "present":true 5 | }, 6 | "facts": { 7 | "selinux.SEPorts": { 8 | "udp": {"53": "dns_port_t"} 9 | }, 10 | "server.Which": { 11 | "command=sepolicy": null 12 | } 13 | }, 14 | "commands": ["semanage port -a -t ssh_port_t -p tcp 22"] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/selinux.port/remove_existing.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["tcp", 22, "ssh_port_t"], 3 | "kwargs": { 4 | "present":false 5 | }, 6 | "facts": { 7 | "selinux.SEPorts": { 8 | "tcp": {"22": "ssh_port_t"} 9 | }, 10 | "server.Which": { 11 | "command=sepolicy": null 12 | } 13 | }, 14 | "commands": [ 15 | "semanage port -d -p tcp 22" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/server.group/add.freebsd.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somegroup"], 3 | "kwargs": { 4 | "gid" : 1000, 5 | "system": true 6 | }, 7 | "facts": { 8 | "server.Groups": [], 9 | "server.Os": "FreeBSD" 10 | }, 11 | "commands": [ 12 | "pw groupadd -n somegroup -g 1000" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/server.group/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somegroup"], 3 | "kwargs": { 4 | "gid" : 1000, 5 | "system": true 6 | }, 7 | "facts": { 8 | "server.Groups": [], 9 | "server.Os": "Linux" 10 | }, 11 | "commands": [ 12 | "groupadd -r somegroup --gid 1000" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/server.group/delete.freebsd.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somegroup"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "server.Groups": [ 8 | "somegroup" 9 | ], 10 | "server.Os": "FreeBSD" 11 | }, 12 | "commands": [ 13 | "pw groupdel -n somegroup" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/server.group/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somegroup"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "server.Groups": [ 8 | "somegroup" 9 | ], 10 | "server.Os": "Linux" 11 | }, 12 | "commands": [ 13 | "groupdel somegroup" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/server.hostname/hostname_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["my-hostname.net"], 3 | "facts": { 4 | "server.Os": "not-Linux", 5 | "server.Hostname": "my-hostname.net", 6 | "server.Which": { 7 | "command=hostnamectl": null 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "hostname is set" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/server.hostname/hostnamectl_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["my-hostname.net"], 3 | "facts": { 4 | "server.Hostname": "my-hostname.net", 5 | "server.Which": { 6 | "command=hostnamectl": "hostnamectl" 7 | } 8 | }, 9 | "commands": [], 10 | "noop_description": "hostname is set" 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/server.modprobe/add-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["mod1", "mod2", "mod3"]], 3 | "facts": { 4 | "server.KernelModules": { 5 | "mod2": {} 6 | } 7 | }, 8 | "commands": [ 9 | "modprobe -a mod1 mod3" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/server.modprobe/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somemodule"], 3 | "facts": { 4 | "server.KernelModules": {} 5 | }, 6 | "commands": [ 7 | "modprobe -a somemodule" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/server.modprobe/add_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somemodule"], 3 | "facts": { 4 | "server.KernelModules": { 5 | "somemodule": {} 6 | } 7 | }, 8 | "commands": [], 9 | "noop_description": "module somemodule is loaded" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/server.modprobe/add_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somemodule"], 3 | "kwargs": { 4 | "force": true 5 | }, 6 | "facts": { 7 | "server.KernelModules": {} 8 | }, 9 | "commands": [ 10 | "modprobe -f -a somemodule" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/server.modprobe/add_multiple_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["somemodule", "someothermodule"]], 3 | "facts": { 4 | "server.KernelModules": { 5 | "somemodule": {}, 6 | "someothermodule": {} 7 | } 8 | }, 9 | "commands": [], 10 | "noop_description": "modules somemodule/someothermodule are loaded" 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/server.modprobe/remove-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["mod1", "mod2", "mod3"]], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "server.KernelModules": { 8 | "mod1": {} 9 | } 10 | }, 11 | "commands": [ 12 | "modprobe -r -a mod1" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/server.modprobe/remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somemodule"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "server.KernelModules": { 8 | "somemodule": {} 9 | } 10 | }, 11 | "commands": [ 12 | "modprobe -r -a somemodule" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/server.mount/mount.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/data"], 3 | "facts": { 4 | "server.Mounts": {} 5 | }, 6 | "commands": [ 7 | "mount /data" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/server.mount/mount_device.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/data"], 3 | "kwargs": { 4 | "device": "/dev/sdb1" 5 | }, 6 | "facts": { 7 | "server.Mounts": {} 8 | }, 9 | "commands": [ 10 | "mount /dev/sdb1 /data" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/server.mount/mount_device_fstype.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/data"], 3 | "kwargs": { 4 | "device": "/dev/sdc3", 5 | "fs_type": "xfs" 6 | }, 7 | "facts": { 8 | "server.Mounts": {} 9 | }, 10 | "commands": [ 11 | "mount -t xfs /dev/sdc3 /data" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/server.mount/mount_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/data"], 3 | "facts": { 4 | "server.Mounts": { 5 | "/data": {} 6 | } 7 | }, 8 | "commands": [], 9 | "noop_description": "filesystem /data is mounted" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/server.mount/mount_options.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/data"], 3 | "kwargs": { 4 | "options": ["rw"] 5 | }, 6 | "facts": { 7 | "server.Mounts": {} 8 | }, 9 | "commands": [ 10 | "mount -o rw /data" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/server.mount/remount_options.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/data"], 3 | "kwargs": { 4 | "options": ["rw", "noatime"] 5 | }, 6 | "facts": { 7 | "server.Mounts": { 8 | "/data": { 9 | "options": ["rw"] 10 | } 11 | } 12 | }, 13 | "commands": [ 14 | "mount -o remount,rw,noatime /data" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/server.mount/unmount.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["/data"], 3 | "kwargs": { 4 | "mounted": false 5 | }, 6 | "facts": { 7 | "server.Mounts": { 8 | "/data": {} 9 | } 10 | }, 11 | "commands": [ 12 | "umount /data" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/server.reboot/reboot.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [], 3 | "commands": [ 4 | ["remove_any_askpass_file", [], {}], 5 | { 6 | "command": "reboot", 7 | "_success_exit_codes": [0, -1] 8 | }, 9 | ["wait_and_reconnect", [], {}], 10 | ["clean_sudo_info", [], {}] 11 | ], 12 | "idempotent": false 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/server.shell/shell.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [[ 3 | "some shell", 4 | "some more shell" 5 | ]], 6 | "commands": [ 7 | "some shell", 8 | "some more shell" 9 | ], 10 | "idempotent": false 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/server.shell/single_shell.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["some shell"], 3 | "commands": [ 4 | "some shell" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/server.sysctl/set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["kern.max-files", 2000], 3 | "facts": { 4 | "server.Sysctl": { 5 | "keys=['kern.max-files']": {} 6 | } 7 | }, 8 | "commands": [ 9 | "sysctl kern.max-files='2000'" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/server.sysctl/set_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["kern.max-files", [2000, 3000]], 3 | "facts": { 4 | "server.Sysctl": { 5 | "keys=['kern.max-files']": {} 6 | } 7 | }, 8 | "commands": [ 9 | "sysctl kern.max-files='2000 3000'" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/server.sysctl/set_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["kern.max-files", 2000], 3 | "facts": { 4 | "server.Sysctl": { 5 | "keys=['kern.max-files']": { 6 | "kern.max-files": 2000 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "sysctl kern.max-files is set to 2000" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/server.sysctl/set_noop_string_value.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["kern.max-files", "2000"], 3 | "facts": { 4 | "server.Sysctl": { 5 | "keys=['kern.max-files']": { 6 | "kern.max-files": 2000 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "sysctl kern.max-files is set to 2000" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/server.sysctl/set_noop_zero_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["kern.max-files", 0], 3 | "facts": { 4 | "server.Sysctl": { 5 | "keys=['kern.max-files']": { 6 | "kern.max-files": 0 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "sysctl kern.max-files is set to 0" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/server.user/add_non_unique.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["someuser"], 3 | "kwargs": { 4 | "unique": false, 5 | "ensure_home": false 6 | }, 7 | "facts": { 8 | "server.Os": "Linux", 9 | "server.Users": {}, 10 | "server.Groups": {} 11 | }, 12 | "commands": [ 13 | "useradd -d /home/someuser -o -M someuser" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/server.wait/port.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "port": 22 4 | }, 5 | "commands": [ 6 | "while ! (netstat -an | grep LISTEN | grep -e \"\\.22\" -e \":22\"); do\n echo \"waiting for port 22...\"\n sleep 1\n done" 7 | ], 8 | "idempotent": false 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/snap.package/install_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "packages": ["vlc"] 4 | }, 5 | "facts": { 6 | "snap.SnapPackage": {}, 7 | "snap.SnapPackages": ["core", "core18", "core20"] 8 | }, 9 | "commands": [ 10 | "snap install vlc --channel=latest/stable" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/snap.package/install_package_classic.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "packages": [ 4 | "nvim" 5 | ], 6 | "classic": true 7 | }, 8 | "facts": { 9 | "snap.SnapPackage": {}, 10 | "snap.SnapPackages": [ 11 | "core", 12 | "core18", 13 | "core20" 14 | ] 15 | }, 16 | "commands": [ 17 | "snap install --classic nvim --channel=latest/stable" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/operations/snap.package/install_package_with_channel.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "packages": ["lxd"], 4 | "channel": "4.0/stable" 5 | }, 6 | "facts": { 7 | "snap.SnapPackage": {}, 8 | "snap.SnapPackages": ["core", "snapd"] 9 | }, 10 | "commands": [ 11 | "snap install lxd --channel=4.0/stable" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/ssh.command/command.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["remote-host.net", "echo hi"], 3 | "commands": [ 4 | "ssh -p 22 remote-host.net 'echo hi'" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/ssh.command/command_quotes.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["remote-host.net", "echo 'hi'"], 3 | "commands": [ 4 | "ssh -p 22 remote-host.net 'echo '\"'\"'hi'\"'\"''" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/ssh.command/command_user_port.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["remote-host.net", "echo hi"], 3 | "kwargs": { 4 | "user": "nick", 5 | "port": 33 6 | }, 7 | "commands": [ 8 | "ssh -p 33 nick@remote-host.net 'echo hi'" 9 | ], 10 | "idempotent": false 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/ssh.download/download_exists.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["remote-host.net", "remote_filename", "local_filename"], 3 | "facts": { 4 | "files.File": { 5 | "path=local_filename": true 6 | } 7 | }, 8 | "commands": [], 9 | "noop_description": "file remote_filename is already downloaded" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/ssh.upload/upload_remote_sudo.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["remote-host.net", "local_filename"], 3 | "kwargs": { 4 | "use_remote_sudo": true 5 | }, 6 | "commands": [ 7 | "scp -P 22 local_filename remote-host.net:_tempfile_", 8 | "ssh -p 22 remote-host.net 'sudo mv _tempfile_ local_filename'" 9 | ], 10 | "idempotent": false 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/ssh.upload/upload_remote_sudo_user.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["remote-host.net", "local_filename"], 3 | "kwargs": { 4 | "user": "test", 5 | "use_remote_sudo": true 6 | }, 7 | "commands": [ 8 | "scp -P 22 local_filename test@remote-host.net:_tempfile_", 9 | "ssh -p 22 test@remote-host.net 'sudo mv _tempfile_ local_filename'" 10 | ], 11 | "idempotent": false 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/systemd.service/running_ambiguous_unit.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["redis-server"], 3 | "facts": { 4 | "systemd.SystemdStatus": { 5 | "machine=None, services=['redis-server.service'], user_mode=False, user_name=None": { 6 | "redis-server.service": false 7 | } 8 | } 9 | }, 10 | "commands": [ 11 | "systemctl start redis-server.service" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/systemd.service/running_noop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["redis-server.service"], 3 | "facts": { 4 | "systemd.SystemdStatus": { 5 | "machine=None, services=['redis-server.service'], user_mode=False, user_name=None": { 6 | "redis-server.service": true 7 | } 8 | } 9 | }, 10 | "commands": [], 11 | "noop_description": "service redis-server.service is running" 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/systemd.service/running_timer.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["some-timer.timer"], 3 | "facts": { 4 | "systemd.SystemdStatus": { 5 | "machine=None, services=['some-timer.timer'], user_mode=False, user_name=None": { 6 | "some-timer.timer": false 7 | } 8 | } 9 | }, 10 | "commands": [ 11 | "systemctl start some-timer.timer" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/systemd.service/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["redis-server.service"], 3 | "facts": { 4 | "systemd.SystemdStatus": { 5 | "machine=None, services=['redis-server.service'], user_mode=False, user_name=None": { 6 | "redis-server.service": false 7 | } 8 | } 9 | }, 10 | "commands": [ 11 | "systemctl start redis-server.service" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/systemd.service/timer.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["logrotate.timer"], 3 | "facts": { 4 | "systemd.SystemdStatus": { 5 | "machine=None, services=['logrotate.timer'], user_mode=False, user_name=None": { 6 | "logrotate.timer": false 7 | } 8 | } 9 | }, 10 | "commands": [ 11 | "systemctl start logrotate.timer" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/sysvinit.service/reload.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "kwargs": { 4 | "reloaded": true 5 | }, 6 | "facts": { 7 | "sysvinit.InitdStatus": { 8 | "nginx": true 9 | } 10 | }, 11 | "commands": [ 12 | "/etc/init.d/nginx reload" 13 | ], 14 | "idempotent": false, 15 | "disable_idempotent_warning_reason": "service reloads are always executed" 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/sysvinit.service/restart.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "kwargs": { 4 | "restarted": true 5 | }, 6 | "facts": { 7 | "sysvinit.InitdStatus": { 8 | "nginx": true 9 | } 10 | }, 11 | "commands": [ 12 | "/etc/init.d/nginx restart" 13 | ], 14 | "idempotent": false, 15 | "disable_idempotent_warning_reason": "service restarts are always executed" 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/sysvinit.service/skip_started.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "facts": { 4 | "sysvinit.InitdStatus": { 5 | "nginx": true 6 | } 7 | }, 8 | "commands": [], 9 | "noop_description": "service nginx is running" 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/sysvinit.service/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "facts": { 4 | "sysvinit.InitdStatus": { 5 | "nginx": false 6 | } 7 | }, 8 | "commands": [ 9 | "/etc/init.d/nginx start" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/sysvinit.service/stop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["nginx"], 3 | "kwargs": { 4 | "running": false 5 | }, 6 | "facts": { 7 | "sysvinit.InitdStatus": { 8 | "nginx": true 9 | } 10 | }, 11 | "commands": [ 12 | "/etc/init.d/nginx stop" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/upstart.service/running.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["redis-server"], 3 | "facts": { 4 | "upstart.UpstartStatus": { 5 | "redis-server": false 6 | } 7 | }, 8 | "commands": [ 9 | "initctl start redis-server" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/vzctl.create/add_template.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "kwargs": { 4 | "template": "ubuntu-1604" 5 | }, 6 | "facts": { 7 | "vzctl.OpenvzContainers": {} 8 | }, 9 | "commands": [ 10 | "vzctl create 123 --ostemplate ubuntu-1604" 11 | ], 12 | "idempotent": false 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/vzctl.create/already_existing.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "kwargs": { 4 | "template": "ubuntu-1604" 5 | }, 6 | "facts": { 7 | "vzctl.OpenvzContainers": [123] 8 | }, 9 | "exception": { 10 | "name": "OperationError", 11 | "message": "An OpenVZ container with CTID 123 already exists" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/operations/vzctl.delete/delete.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "commands": [ 4 | "vzctl delete 123" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/vzctl.mount/mount.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "commands": [ 4 | "vzctl mount 123" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/vzctl.restart/restart.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "commands": [ 4 | "vzctl stop 123", 5 | "vzctl start 123" 6 | ], 7 | "idempotent": false 8 | } 9 | -------------------------------------------------------------------------------- /tests/operations/vzctl.restart/restart_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "kwargs": { 4 | "force": true 5 | }, 6 | "commands": [ 7 | "vzctl stop 123", 8 | "vzctl start 123 --force" 9 | ], 10 | "idempotent": false 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/vzctl.set/set.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "kwargs": { 4 | "hostname": "my-host.name" 5 | }, 6 | "commands": [ 7 | "vzctl set 123 --save --hostname my-host.name" 8 | ], 9 | "idempotent": false 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/vzctl.set/set_multiple.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "kwargs": { 4 | "ipadd": ["192.168.1.1", "192.168.1.2"] 5 | }, 6 | "commands": [ 7 | "vzctl set 123 --save --ipadd 192.168.1.1 --ipadd 192.168.1.2" 8 | ], 9 | "idempotent": false 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/vzctl.set/set_no_save.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "kwargs": { 4 | "save": false, 5 | "hostname": "my-host.name" 6 | }, 7 | "commands": [ 8 | "vzctl set 123 --hostname my-host.name" 9 | ], 10 | "idempotent": false 11 | } 12 | -------------------------------------------------------------------------------- /tests/operations/vzctl.start/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "commands": [ 4 | "vzctl start 123" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/vzctl.start/start_force.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "kwargs": { 4 | "force": true 5 | }, 6 | "commands": [ 7 | "vzctl start 123 --force" 8 | ], 9 | "idempotent": false 10 | } 11 | -------------------------------------------------------------------------------- /tests/operations/vzctl.stop/stop.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "commands": [ 4 | "vzctl stop 123" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/vzctl.unmount/unmount.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [123], 3 | "commands": [ 4 | "vzctl umount 123" 5 | ], 6 | "idempotent": false 7 | } 8 | -------------------------------------------------------------------------------- /tests/operations/xbps.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["curl"], 3 | "facts": { 4 | "xbps.XbpsPackages": {} 5 | }, 6 | "commands": [ 7 | "xbps-install -y -u curl" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/operations/xbps.packages/remove_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [["curl", "i-dont-exist"]], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "xbps.XbpsPackages": { 8 | "curl": "1" 9 | } 10 | }, 11 | "commands": [ 12 | "xbps-remove -y curl" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/yum.key/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["mykey"], 3 | "commands": [ 4 | "rpm --import mykey" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /tests/operations/yum.packages/add_packages_alias.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [[ 3 | "vim" 4 | ]], 5 | "facts": { 6 | "rpm.RpmPackages": {}, 7 | "rpm.RpmPackageProvides": { 8 | "package=vim": [["vim-enhanced", "1.2.3"]] 9 | } 10 | }, 11 | "commands": [ 12 | "yum install -y vim" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/yum.packages/add_packages_alias_different_version.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [[ 3 | "vim" 4 | ]], 5 | "facts": { 6 | "rpm.RpmPackages": { 7 | "vim-enhanced": ["2.3.4"] 8 | }, 9 | "rpm.RpmPackageProvides": { 10 | "package=vim": [["vim-enhanced", "1.2.3"]] 11 | } 12 | }, 13 | "commands": [ 14 | "yum install -y vim" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/yum.packages/install_with_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ "docker-ce"], 3 | "kwargs": { 4 | "extra_install_args": "--foo" 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {}, 8 | "rpm.RpmPackageProvides": { 9 | "package=docker-ce": null 10 | } 11 | }, 12 | "commands": [ 13 | "yum install -y --foo docker-ce" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/yum.packages/install_with_nobest.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ "docker-ce"], 3 | "kwargs": { 4 | "nobest": "true" 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {}, 8 | "rpm.RpmPackageProvides": { 9 | "package=docker-ce": null 10 | } 11 | }, 12 | "commands": [ 13 | "yum install -y --nobest docker-ce" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/yum.packages/noop_add_packages_alias.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [[ 3 | "vim" 4 | ]], 5 | "facts": { 6 | "rpm.RpmPackages": { 7 | "vim-enhanced": ["1.2.3"] 8 | }, 9 | "rpm.RpmPackageProvides": { 10 | "package=vim": [["vim-enhanced", "1.2.3"]] 11 | } 12 | }, 13 | "commands": [], 14 | "noop_description": "package vim is installed" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/yum.packages/update_clean.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "update": true, 4 | "clean": true 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {}, 8 | "rpm.RpmPackageProvides": {} 9 | }, 10 | "commands": [ 11 | "yum clean all", 12 | "yum update -y" 13 | ], 14 | "idempotent": false, 15 | "disable_idempotent_warning_reason": "package upgrades are always executed" 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/yum.repo/remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somerepo"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "files.File": { 8 | "path=/etc/yum.repos.d/somerepo.repo": { 9 | "mode": 0 10 | } 11 | } 12 | }, 13 | "commands": ["rm -f /etc/yum.repos.d/somerepo.repo"] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/yum.rpm/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["something.rpm"], 3 | "facts": { 4 | "rpm.RpmPackages": {}, 5 | "rpm.RpmPackage": { 6 | "package=something.rpm": { 7 | "name": "something", 8 | "version": "abc" 9 | }, 10 | "package=something": null 11 | } 12 | }, 13 | "commands": [ 14 | "rpm -i something.rpm" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/yum.rpm/add_existing_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["something.rpm"], 3 | "facts": { 4 | "rpm.RpmPackage": { 5 | "package=something.rpm": { 6 | "name": "something", 7 | "version": "1.1" 8 | }, 9 | "package=something": { 10 | "version": "1.0" 11 | } 12 | } 13 | }, 14 | "commands": ["rpm -i something.rpm"] 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/create.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home/james 3 | kwargs: 4 | present: true 5 | mountpoint: /home/james 6 | properties: 7 | "com.sun:auto_snapshot": 'true' 8 | facts: 9 | zfs.ZfsDatasets: {} 10 | commands: 11 | - zfs create -o com.sun:auto_snapshot=true -o mountpoint=/home/james tank/home/james 12 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/create_noop.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home/james 3 | kwargs: 4 | present: true 5 | compression: lz4 6 | facts: 7 | zfs.ZfsDatasets: 8 | tank/home/james: 9 | compression: lz4 10 | commands: [] 11 | noop_description: tank/home/james is already present 12 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/create_recursive.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/myzvol 3 | kwargs: 4 | present: true 5 | recursive: true 6 | compression: lz4 7 | facts: 8 | zfs.ZfsDatasets: {} 9 | commands: 10 | - zfs create -o compression=lz4 -p tank/myzvol 11 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/create_sparse.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/myzvol 3 | kwargs: 4 | present: true 5 | sparse: true 6 | compression: lz4 7 | volume_size: 5G 8 | facts: 9 | zfs.ZfsDatasets: {} 10 | commands: 11 | - zfs create -V 5G -o compression=lz4 -s tank/myzvol 12 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/create_volume.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/myzvol 3 | kwargs: 4 | present: true 5 | compression: lz4 6 | volume_size: 5G 7 | facts: 8 | zfs.ZfsDatasets: {} 9 | commands: 10 | - zfs create -V 5G -o compression=lz4 tank/myzvol 11 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/delete.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home/james 3 | kwargs: 4 | present: false 5 | facts: 6 | zfs.ZfsDatasets: 7 | tank/home/james: 8 | mountpoint: /home/james 9 | commands: 10 | - zfs destroy tank/home/james 11 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/delete_noop.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home/james 3 | kwargs: 4 | present: false 5 | facts: 6 | zfs.ZfsDatasets: {} 7 | commands: [] 8 | noop_description: tank/home/james is already absent 9 | -------------------------------------------------------------------------------- /tests/operations/zfs.dataset/delete_recursive.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home 3 | kwargs: 4 | present: false 5 | recursive: true 6 | facts: 7 | zfs.ZfsDatasets: 8 | tank/home: 9 | mountpoint: /home 10 | tank/home/james: 11 | mountpoint: /home/james 12 | commands: 13 | - zfs destroy -r tank/home 14 | -------------------------------------------------------------------------------- /tests/operations/zfs.filesystem/create.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home/james 3 | kwargs: 4 | present: true 5 | mountpoint: /home/james 6 | properties: 7 | "com.sun:auto_snapshot": 'true' 8 | facts: 9 | zfs.ZfsDatasets: {} 10 | commands: 11 | - zfs create -o com.sun:auto_snapshot=true -o mountpoint=/home/james tank/home/james 12 | -------------------------------------------------------------------------------- /tests/operations/zfs.filesystem/delete.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home/james 3 | kwargs: 4 | present: false 5 | facts: 6 | zfs.ZfsDatasets: 7 | tank/home/james: 8 | mountpoint: /home/james 9 | commands: 10 | - zfs destroy tank/home/james 11 | -------------------------------------------------------------------------------- /tests/operations/zfs.snapshot/create.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/home/james@2024-02-29 3 | kwargs: 4 | present: true 5 | properties: 6 | "com.example:created_timestamp": '1583020799' 7 | facts: 8 | zfs.ZfsSnapshots: {} 9 | commands: 10 | - zfs snap -o com.example:created_timestamp=1583020799 tank/home/james@2024-02-29 11 | -------------------------------------------------------------------------------- /tests/operations/zfs.volume/create.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - tank/myzvol 3 | - 5G 4 | kwargs: 5 | present: true 6 | compression: lz4 7 | facts: 8 | zfs.ZfsDatasets: {} 9 | commands: 10 | - zfs create -V 5G -o compression=lz4 tank/myzvol 11 | -------------------------------------------------------------------------------- /tests/operations/zypper.key/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["mykey"], 3 | "commands": [ 4 | "rpm --import mykey" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /tests/operations/zypper.packages/add_packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [[ 3 | "git", 4 | "python-devel", 5 | "MozillaFirefox", 6 | "something" 7 | ]], 8 | "facts": { 9 | "rpm.RpmPackages": { 10 | "something": [""] 11 | } 12 | }, 13 | "commands": [ 14 | "zypper --non-interactive install -y git python-devel MozillaFirefox" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/zypper.packages/install_with_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ "docker-ce"], 3 | "kwargs": { 4 | "extra_install_args": "--foo" 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {} 8 | }, 9 | "commands": [ 10 | "zypper --non-interactive install -y --foo docker-ce" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/zypper.packages/install_with_global_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [ "docker-ce"], 3 | "kwargs": { 4 | "extra_global_install_args": "--bar" 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {} 8 | }, 9 | "commands": [ 10 | "zypper --bar --non-interactive install -y docker-ce" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/operations/zypper.packages/uninstall_with_args.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": [[ 3 | "git" 4 | ]], 5 | "kwargs": { 6 | "present": false, 7 | "extra_uninstall_args": "--force" 8 | }, 9 | "facts": { 10 | "rpm.RpmPackages": { 11 | "git": [""] 12 | } 13 | }, 14 | "commands": [ 15 | "zypper --non-interactive remove -y --force git" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/operations/zypper.packages/update_clean.json: -------------------------------------------------------------------------------- 1 | { 2 | "kwargs": { 3 | "update": true, 4 | "clean": true 5 | }, 6 | "facts": { 7 | "rpm.RpmPackages": {} 8 | }, 9 | "commands": [ 10 | "zypper clean --all", 11 | "zypper update -y" 12 | ], 13 | "idempotent": false, 14 | "disable_idempotent_warning_reason": "package upgrades are always executed" 15 | } 16 | -------------------------------------------------------------------------------- /tests/operations/zypper.repo/remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["somerepo", "http://baseurl"], 3 | "kwargs": { 4 | "present": false 5 | }, 6 | "facts": { 7 | "files.File": { 8 | "path=/etc/zypp/repos.d/somerepo.repo": { 9 | "mode": 0 10 | } 11 | } 12 | }, 13 | "commands": ["rm -f /etc/zypp/repos.d/somerepo.repo"] 14 | } 15 | -------------------------------------------------------------------------------- /tests/operations/zypper.rpm/add.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["something.rpm"], 3 | "facts": { 4 | "rpm.RpmPackages": {}, 5 | "rpm.RpmPackage": { 6 | "package=something.rpm": { 7 | "name": "something", 8 | "version": "abc" 9 | }, 10 | "package=something": null 11 | } 12 | }, 13 | "commands": [ 14 | "rpm -i something.rpm" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/operations/zypper.rpm/add_existing_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "args": ["something.rpm"], 3 | "facts": { 4 | "rpm.RpmPackage": { 5 | "package=something.rpm": { 6 | "name": "something", 7 | "version": "1.1" 8 | }, 9 | "package=something": { 10 | "version": "1.0" 11 | } 12 | } 13 | }, 14 | "commands": ["rpm -i something.rpm"] 15 | } 16 | -------------------------------------------------------------------------------- /tests/test_api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/tests/test_api/__init__.py -------------------------------------------------------------------------------- /tests/test_cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/tests/test_cli/__init__.py -------------------------------------------------------------------------------- /tests/test_cli/deploy/files/a_file: -------------------------------------------------------------------------------- 1 | this is a file! 2 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/group_data/all.py: -------------------------------------------------------------------------------- 1 | hello = "world" 2 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/group_data/invalid.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/tests/test_cli/deploy/group_data/invalid.json -------------------------------------------------------------------------------- /tests/test_cli/deploy/group_data/leftover_data.py: -------------------------------------------------------------------------------- 1 | still_parsed = "never_used" 2 | _global_arg = "gets_parsed" 3 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/inventories/inventory.py: -------------------------------------------------------------------------------- 1 | hosts = ( 2 | [ 3 | "somehost", 4 | ("anotherhost", {"ssh_port": 1022}), 5 | ], 6 | {}, 7 | ) 8 | 9 | generator_hosts = (host for host in ("hosta", "hostb")) 10 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/inventories/inventory_all.py: -------------------------------------------------------------------------------- 1 | hosts = ( 2 | [ 3 | "somehost", 4 | ("anotherhost", {"ssh_port": 1022}), 5 | ], 6 | {}, 7 | ) 8 | 9 | generator_hosts = (host for host in ("hosta", "hostb")) 10 | 11 | all = (["somehost"], {}) 12 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/inventories/inventory_ansible: -------------------------------------------------------------------------------- 1 | [webservers] 2 | webserver-[1:2].net 3 | webserver-3.net 4 | 5 | [dbservers] 6 | dbserver-[01:02].net 7 | 8 | [web_and_db_servers:children] 9 | webservers 10 | dbservers 11 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/inventories/inventory_ansible.yml: -------------------------------------------------------------------------------- 1 | all: 2 | hosts: 3 | mail.example.com: 4 | children: 5 | webservers: 6 | hosts: 7 | foo.example.com: 8 | bar.example.com: 9 | dbservers: 10 | hosts: 11 | one.example.com: 12 | two.example.com: 13 | three.example.com: 14 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/tasks/another_task.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import server 2 | 3 | server.shell( 4 | name="Second task operation", 5 | commands="echo second_task_operation", 6 | ) 7 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/tasks/b_task.py: -------------------------------------------------------------------------------- 1 | from pyinfra import host 2 | from pyinfra.operations import server 3 | 4 | server.shell( 5 | name=f"{host.data.get('keyword')} task operation", 6 | commands=f"echo {host.data.get('id')}", 7 | ) 8 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/tasks/nested/empty_task.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/tests/test_cli/deploy/tasks/nested/empty_task.py -------------------------------------------------------------------------------- /tests/test_cli/deploy/templates/a_template.j2: -------------------------------------------------------------------------------- 1 | {% if is_template %} 2 | This is a template! 3 | {% endif %} 4 | -------------------------------------------------------------------------------- /tests/test_cli/deploy/utils.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import files 2 | 3 | 4 | def call_file_op(): 5 | files.put( 6 | name="Third main operation", 7 | src="files/a_file", 8 | dest="/a_file", 9 | ) 10 | -------------------------------------------------------------------------------- /tests/test_cli/deploy_fails/invalid_argument_type.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import server 2 | 3 | server.shell(commands="uptime", _sudo=None) 4 | -------------------------------------------------------------------------------- /tests/test_cli/deploy_fails/invalid_operation_arg.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import server 2 | 3 | server.shell(invalid_arg=None) 4 | -------------------------------------------------------------------------------- /tests/test_cli/deploy_fails/operation_error.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import files 2 | 3 | files.directory(path="operation_error.py") 4 | -------------------------------------------------------------------------------- /tests/test_cli/inventories/invalid.py: -------------------------------------------------------------------------------- 1 | # Variables names with a leading underscore are ignored 2 | _hosts = ["host-1", "host-2", "host-3"] 3 | 4 | # Dictionaries are not supported 5 | dict_hosts = { 6 | "host-1": "hostname", 7 | } 8 | 9 | # Generators are not supported 10 | generator_hosts = (host for host in ["host-1", "host-2"]) 11 | 12 | # https://github.com/pyinfra-dev/pyinfra/issues/662 13 | issue_662 = ["a", "b", ({"foo": "bar"})] 14 | -------------------------------------------------------------------------------- /tests/test_cli/user/test_ops.py: -------------------------------------------------------------------------------- 1 | from pyinfra.api import operation 2 | 3 | 4 | @operation() 5 | def dummy_op(arg1, arg2, state=None, host=None): 6 | yield "echo arg1={0} arg2={1}".format(arg1, arg2) 7 | -------------------------------------------------------------------------------- /tests/test_cli/util.py: -------------------------------------------------------------------------------- 1 | from os import chdir, getcwd 2 | 3 | from click.testing import CliRunner 4 | 5 | import pyinfra 6 | from pyinfra_cli.main import cli 7 | 8 | 9 | def run_cli(*arguments): 10 | cwd = getcwd() 11 | pyinfra.is_cli = True 12 | runner = CliRunner() 13 | result = runner.invoke(cli, arguments, standalone_mode=False) 14 | pyinfra.is_cli = False 15 | chdir(cwd) 16 | return result 17 | -------------------------------------------------------------------------------- /tests/test_connectors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyinfra-dev/pyinfra/b87c7809fae8cfa427683577a1ee00627c97d6b6/tests/test_connectors/__init__.py -------------------------------------------------------------------------------- /tests/typing/invalid/operation_kwarg.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import files, server 2 | 3 | server.shell(commands=[], _invalid_kwarg=True) 4 | 5 | files.line(path="path", line="line", _sudo=True, _invalid_kwarg=False) 6 | -------------------------------------------------------------------------------- /tests/typing/invalid/operation_kwarg_value.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import server 2 | 3 | server.shell(commands=[], _sudo="True") 4 | -------------------------------------------------------------------------------- /tests/typing/valid/operation.py: -------------------------------------------------------------------------------- 1 | from pyinfra.operations import files, server 2 | 3 | server.shell(commands=[], _sudo=True, _sudo_user="pyinfra") 4 | 5 | files.line(path="path", line="line", _sudo=True) 6 | --------------------------------------------------------------------------------