Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

#!/usr/bin/python 

# -*- coding: utf-8 -*- 

 

# Copyright: (c) 2018, Kevin Breit (@kbreit) <kevin.breit@kevinbreit.net> 

# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 

 

from __future__ import absolute_import, division, print_function 

__metaclass__ = type 

 

ANSIBLE_METADATA = { 

'metadata_version': '1.1', 

'status': ['preview'], 

'supported_by': 'community' 

} 

 

DOCUMENTATION = r''' 

--- 

module: meraki_syslog 

short_description: Manage syslog server settings in the Meraki cloud. 

version_added: "2.8" 

description: 

- Allows for creation and management of Syslog servers within Meraki. 

notes: 

- Changes to existing syslog servers replaces existing configuration. If you need to add to an 

existing configuration set state to query to gather the existing configuration and then modify or add. 

options: 

auth_key: 

description: 

- Authentication key provided by the dashboard. Required if environmental variable MERAKI_KEY is not set. 

type: str 

state: 

description: 

- Query or edit syslog servers 

- To delete a syslog server, do not include server in list of servers 

choices: [present, query] 

default: present 

type: str 

net_name: 

description: 

- Name of a network. 

aliases: [name, network] 

type: str 

net_id: 

description: 

- ID number of a network. 

type: str 

servers: 

description: 

- List of syslog server settings 

type: list 

suboptions: 

host: 

description: 

- IP address or hostname of Syslog server. 

type: str 

port: 

description: 

- Port number Syslog server is listening on. 

default: "514" 

type: int 

roles: 

description: 

- List of applicable Syslog server roles. 

choices: ['Wireless Event log', 

'Appliance event log', 

'Switch event log', 

'Air Marshal events', 

'Flows', 

'URLs', 

'IDS alerts', 

'Security events'] 

type: list 

 

author: 

- Kevin Breit (@kbreit) 

extends_documentation_fragment: meraki 

''' 

 

EXAMPLES = r''' 

- name: Query syslog configurations on network named MyNet in the YourOrg organization 

meraki_syslog: 

auth_key: abc12345 

status: query 

org_name: YourOrg 

net_name: MyNet 

delegate_to: localhost 

 

- name: Add single syslog server with Appliance event log role 

meraki_syslog: 

auth_key: abc12345 

status: query 

org_name: YourOrg 

net_name: MyNet 

servers: 

- host: 192.0.1.2 

port: 514 

roles: 

- Appliance event log 

delegate_to: localhost 

 

- name: Add multiple syslog servers 

meraki_syslog: 

auth_key: abc12345 

status: query 

org_name: YourOrg 

net_name: MyNet 

servers: 

- host: 192.0.1.2 

port: 514 

roles: 

- Appliance event log 

- host: 192.0.1.3 

port: 514 

roles: 

- Appliance event log 

- Flows 

delegate_to: localhost 

''' 

 

RETURN = r''' 

data: 

description: Information about the created or manipulated object. 

returned: info 

type: complex 

contains: 

host: 

description: Hostname or IP address of syslog server. 

returned: success 

type: str 

sample: 192.0.1.1 

port: 

description: Port number for syslog communication. 

returned: success 

type: str 

sample: 443 

roles: 

description: List of roles assigned to syslog server. 

returned: success 

type: list 

sample: "Wireless event log, URLs" 

''' 

 

from ansible.module_utils.basic import AnsibleModule, json 

from ansible_collections.cisco.meraki.plugins.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec 

 

 

def main(): 

 

# define the available arguments/parameters that a user can pass to 

# the module 

 

server_arg_spec = dict(host=dict(type='str'), 

port=dict(type='int', default="514"), 

roles=dict(type='list', choices=['Wireless Event log', 

'Appliance event log', 

'Switch event log', 

'Air Marshal events', 

'Flows', 

'URLs', 

'IDS alerts', 

'Security events', 

]), 

) 

 

argument_spec = meraki_argument_spec() 

argument_spec.update(net_id=dict(type='str'), 

servers=dict(type='list', element='dict', options=server_arg_spec), 

state=dict(type='str', choices=['present', 'query'], default='present'), 

net_name=dict(type='str', aliases=['name', 'network']), 

) 

 

# the AnsibleModule object will be our abstraction working with Ansible 

# this includes instantiation, a couple of common attr would be the 

# args/params passed to the execution, as well as if the module 

# supports check mode 

module = AnsibleModule(argument_spec=argument_spec, 

supports_check_mode=True, 

) 

 

meraki = MerakiModule(module, function='syslog') 

module.params['follow_redirects'] = 'all' 

payload = None 

 

syslog_urls = {'syslog': '/networks/{net_id}/syslogServers'} 

meraki.url_catalog['query_update'] = syslog_urls 

 

187 ↛ 188line 187 didn't jump to line 188, because the condition on line 187 was never true if not meraki.params['org_name'] and not meraki.params['org_id']: 

meraki.fail_json(msg='org_name or org_id parameters are required') 

189 ↛ 192line 189 didn't jump to line 192, because the condition on line 189 was never false if meraki.params['state'] != 'query': 

190 ↛ 191line 190 didn't jump to line 191, because the condition on line 190 was never true if not meraki.params['net_name'] and not meraki.params['net_id']: 

meraki.fail_json(msg='net_name or net_id is required for present or absent states') 

192 ↛ 193line 192 didn't jump to line 193, because the condition on line 192 was never true if meraki.params['net_name'] and meraki.params['net_id']: 

meraki.fail_json(msg='net_name and net_id are mutually exclusive') 

 

# if the user is working with this module in only check mode we do not 

# want to make any changes to the environment, just return the current 

# state with no modifications 

 

# manipulate or modify the state as needed (this is going to be the 

# part where your module will do what it needs to do) 

 

org_id = meraki.params['org_id'] 

203 ↛ 205line 203 didn't jump to line 205, because the condition on line 203 was never false if not org_id: 

org_id = meraki.get_org_id(meraki.params['org_name']) 

net_id = meraki.params['net_id'] 

206 ↛ 210line 206 didn't jump to line 210, because the condition on line 206 was never false if net_id is None: 

nets = meraki.get_nets(org_id=org_id) 

net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) 

 

210 ↛ 211line 210 didn't jump to line 211, because the condition on line 210 was never true if meraki.params['state'] == 'query': 

path = meraki.construct_path('query_update', net_id=net_id) 

r = meraki.request(path, method='GET') 

if meraki.status == 200: 

meraki.result['data'] = r 

215 ↛ 251line 215 didn't jump to line 251, because the condition on line 215 was never false elif meraki.params['state'] == 'present': 

# Construct payload 

payload = dict() 

payload['servers'] = meraki.params['servers'] 

 

# Convert port numbers to string for idempotency checks 

for server in payload['servers']: 

222 ↛ 221line 222 didn't jump to line 221, because the condition on line 222 was never false if server['port']: 

server['port'] = str(server['port']) 

path = meraki.construct_path('query_update', net_id=net_id) 

r = meraki.request(path, method='GET') 

226 ↛ 230line 226 didn't jump to line 230, because the condition on line 226 was never false if meraki.status == 200: 

original = dict() 

original['servers'] = r 

 

230 ↛ 244line 230 didn't jump to line 244, because the condition on line 230 was never false if meraki.is_update_required(original, payload): 

231 ↛ 232line 231 didn't jump to line 232, because the condition on line 231 was never true if meraki.module.check_mode is True: 

meraki.generate_diff(original, payload) 

original.update(payload) 

meraki.result['data'] = original 

meraki.result['changed'] = True 

meraki.exit_json(**meraki.result) 

path = meraki.construct_path('query_update', net_id=net_id) 

r = meraki.request(path, method='PUT', payload=json.dumps(payload)) 

239 ↛ 251line 239 didn't jump to line 251, because the condition on line 239 was never false if meraki.status == 200: 

meraki.generate_diff(original, r) 

meraki.result['data'] = r 

meraki.result['changed'] = True 

else: 

if meraki.module.check_mode is True: 

meraki.result['data'] = original 

meraki.exit_json(**meraki.result) 

meraki.result['data'] = original 

 

# in the event of a successful module execution, you will want to 

# simple AnsibleModule.exit_json(), passing the key/value results 

meraki.exit_json(**meraki.result) 

 

 

254 ↛ exitline 254 didn't exit the module, because the condition on line 254 was never falseif __name__ == '__main__': 

main()