|
40 | 40 | type: bool |
41 | 41 | required: false |
42 | 42 | default: false |
| 43 | + online: |
| 44 | + description: |
| 45 | + When true, use the D-Bus API to query the status from the running system. |
| 46 | + Otherwise, use firewall-offline-cmd(1). Offline mode is (currently) |
| 47 | + incompatible with "detailed" mode. |
| 48 | + type: bool |
| 49 | + required: false |
| 50 | + default: true |
43 | 51 | author: Brennan Paciorek (@BrennanPaciorek) |
44 | 52 | """ |
45 | 53 |
|
|
92 | 100 | HAS_POLICIES = False |
93 | 101 |
|
94 | 102 |
|
| 103 | +def offline_cmd(module, args, defaults=False): |
| 104 | + # get the defaults by disabling the --system-config dir (ETC_FIREWALLD) |
| 105 | + conf_args = ["--system-config=/nonexisting"] if defaults else [] |
| 106 | + return module.run_command( |
| 107 | + ["firewall-offline-cmd"] + conf_args + args, |
| 108 | + check_rc=True, |
| 109 | + )[1].strip() |
| 110 | + |
| 111 | + |
95 | 112 | def config_to_dict(module): |
96 | 113 | detailed = module.params.get("detailed", False) |
| 114 | + online = module.params.get("online", True) |
97 | 115 | config = {} |
98 | 116 | defaults = {} |
99 | 117 | custom = {} |
100 | 118 | setting_list = ["zones", "services", "icmptypes", "helpers", "ipsets"] |
101 | 119 |
|
| 120 | + if detailed and not online: |
| 121 | + module.fail_json(msg="detailed information not available in offline mode") |
| 122 | + |
102 | 123 | if HAS_POLICIES: |
103 | 124 | setting_list.append("policies") |
104 | 125 |
|
105 | | - fw = FirewallClient() |
| 126 | + if online: |
| 127 | + fw = FirewallClient() |
| 128 | + |
| 129 | + for setting in setting_list: |
| 130 | + default_setting_dir = os.path.join( |
| 131 | + firewall.config.USR_LIB_FIREWALLD, setting |
| 132 | + ) |
| 133 | + custom_setting_dir = os.path.join(firewall.config.ETC_FIREWALLD, setting) |
106 | 134 |
|
107 | | - for setting in setting_list: |
108 | | - default_setting_dir = os.path.join(firewall.config.USR_LIB_FIREWALLD, setting) |
109 | | - custom_setting_dir = os.path.join(firewall.config.ETC_FIREWALLD, setting) |
| 135 | + settings = fetch_settings_from_dir(default_setting_dir, detailed, fw) |
| 136 | + if settings: |
| 137 | + defaults[setting] = settings |
| 138 | + settings = fetch_settings_from_dir(custom_setting_dir, True, fw) |
| 139 | + if settings: |
| 140 | + custom[setting] = settings |
110 | 141 |
|
111 | | - settings = fetch_settings_from_dir(default_setting_dir, detailed, fw) |
112 | | - if settings: |
113 | | - defaults[setting] = settings |
114 | | - settings = fetch_settings_from_dir(custom_setting_dir, True, fw) |
115 | | - if settings: |
116 | | - custom[setting] = settings |
| 142 | + config["default_zone"] = fw.getDefaultZone() |
| 143 | + else: |
| 144 | + # get the default settings |
| 145 | + for setting in setting_list: |
| 146 | + values = offline_cmd(module, ["--get-" + setting], defaults=True).split() |
| 147 | + # zone services are important, so make them a dict, not a plain list (same as with online mode) |
| 148 | + if setting == "zones": |
| 149 | + for zone in values: |
| 150 | + services = offline_cmd( |
| 151 | + module, ["--zone", zone, "--list-services"], defaults=True |
| 152 | + ).split() |
| 153 | + defaults.setdefault("zones", {})[zone] = {"services": services} |
| 154 | + else: |
| 155 | + defaults[setting] = values |
| 156 | + |
| 157 | + # compute the custom settings by diffing with defaults |
| 158 | + for setting in setting_list: |
| 159 | + values = offline_cmd(module, ["--get-" + setting]).split() |
| 160 | + if setting == "zones": |
| 161 | + for zone in values: |
| 162 | + services = offline_cmd( |
| 163 | + module, ["--zone", zone, "--list-services"] |
| 164 | + ).split() |
| 165 | + # add zone to custom if the whole zone is new or its services changed |
| 166 | + if zone not in defaults["zones"] or ( |
| 167 | + set(services) - set(defaults["zones"][zone]["services"]) |
| 168 | + ): |
| 169 | + custom.setdefault("zones", {})[zone] = {"services": services} |
| 170 | + else: |
| 171 | + diff = set(values) - set(defaults[setting]) |
| 172 | + if diff: |
| 173 | + custom[setting] = sorted(diff) |
| 174 | + |
| 175 | + config["default_zone"] = offline_cmd(module, ["--get-default-zone"]) |
117 | 176 |
|
118 | 177 | if defaults: |
119 | 178 | config["default"] = defaults |
120 | 179 | if custom: |
121 | 180 | config["custom"] = custom |
122 | | - config["default_zone"] = fw.getDefaultZone() |
123 | | - |
124 | 181 | return config |
125 | 182 |
|
126 | 183 |
|
@@ -198,7 +255,10 @@ def fetch_settings_from_dir(directory, detailed=False, fw=None): |
198 | 255 |
|
199 | 256 | def main(): |
200 | 257 |
|
201 | | - module_args = dict(detailed=dict(type="bool", default=False, required=False)) |
| 258 | + module_args = dict( |
| 259 | + detailed=dict(type="bool", default=False, required=False), |
| 260 | + online=dict(type="bool", default=True, required=False), |
| 261 | + ) |
202 | 262 |
|
203 | 263 | results = dict(changed=False, firewall_config=dict()) |
204 | 264 |
|
|
0 commit comments