/
nat_worker.py
190 lines (147 loc) · 5.42 KB
/
nat_worker.py
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
from pylc.models.livegateapi import Nat
from utils import json_response, validate_json_obj, \
validate_json_obj_list
from const import SUCCESS, HTTP_OK, INVALID_POST_DATA, HTTP_BAD_REQUEST, \
SERVER_ERROR, HTTP_INTERNAL_SERVER_ERROR, \
ROUTER_SCRIPT, SNAT, DNAT, NF_APPEND, ANY_IF, MIN_IPV4, MAX_IPV4
from logger import log
from task import cmd_waiting_queues_put, cmd_response_get, router_hash, \
PseudoGeventQueue
# SNAT
@validate_json_obj(obj_cls=Nat)
def create_snat(nat, router_id):
return create_nat(SNAT, router_id, nat)
def read_snat(router_id, rule_id=None):
return read_nat(SNAT, router_id, rule_id)
@validate_json_obj_list(obj_cls=Nat)
def update_snat(nats, router_id):
return update_nat(SNAT, router_id, nats)
def delete_snat(router_id, rule_id):
return delete_nat(SNAT, router_id, rule_id)
# DNAT
@validate_json_obj(obj_cls=Nat)
def create_dnat(nat, router_id):
return create_nat(DNAT, router_id, nat)
def read_dnat(router_id, rule_id=None):
return read_nat(DNAT, router_id, rule_id)
@validate_json_obj_list(obj_cls=Nat)
def update_dnat(nats, router_id):
return update_nat(DNAT, router_id, nats)
def delete_dnat(router_id, rule_id):
return delete_nat(DNAT, router_id, rule_id)
# utils
def create_nat(nat_type, router_id, nat):
return config_nat(NF_APPEND, nat_type, router_id, None, nat)
def read_nat(nat_type, router_id, rule_id=None):
# TODO
log.debug('%s nat_id: %d-%r' % (nat_type, router_id, rule_id))
return json_response(status=SUCCESS), HTTP_OK
def update_nat(nat_type, router_id, nats):
key = ('update', 'nat', nat_type, str(router_id))
message = []
args = [
ROUTER_SCRIPT,
'flush', 'nat',
nat_type,
str(router_id),
]
message.append(args)
for nat in sorted(nats, cmp=lambda x, y: cmp(x.rule_id, y.rule_id)):
args, constrains = get_config_nat_args(NF_APPEND, nat_type,
router_id, nat)
if constrains is not None:
return json_response(
status=INVALID_POST_DATA, description=constrains
), HTTP_BAD_REQUEST
message.append(args)
ret_queue = PseudoGeventQueue()
cmd_waiting_queues_put(router_id,
router_hash,
key,
message,
ret_queue)
output = cmd_response_get(ret_queue)
if output:
return json_response(
status=SERVER_ERROR, description=output
), HTTP_INTERNAL_SERVER_ERROR
return json_response(status=SUCCESS), HTTP_OK
def delete_nat(nat_type, router_id, rule_id):
key = ('delete', 'nat', nat_type, str(router_id), str(rule_id))
args = [
ROUTER_SCRIPT,
'delete', 'nat',
nat_type,
str(router_id),
str(rule_id),
]
ret_queue = PseudoGeventQueue()
cmd_waiting_queues_put(router_id,
router_hash,
key,
args,
ret_queue)
output = cmd_response_get(ret_queue)
if output:
return json_response(
status=SERVER_ERROR, description=output
), HTTP_INTERNAL_SERVER_ERROR
return json_response(status=SUCCESS), HTTP_OK
def get_config_nat_args(nf_command, nat_type, router_id, nat):
if nat_type == SNAT:
if nat.target.min_address != MIN_IPV4 or \
nat.target.max_address != MAX_IPV4:
nat.target.if_type = ANY_IF
nat.target.if_index = 0
constrains = None
if nat_type == SNAT and nat.match.if_type != ANY_IF:
constrains = 'Can not set MATCH IF_TYPE if NAT_TYPE is SNAT'
elif nat_type == DNAT and nat.target.if_type != ANY_IF:
constrains = 'Can not set TARGET IF_TYPE if NAT_TYPE is DNAT'
if constrains is not None:
return [], constrains
args = [
ROUTER_SCRIPT,
nf_command, 'nat',
nat_type,
str(router_id),
str(nat.rule_id),
str(nat.isp),
str(nat.protocol),
nat.match.if_type,
str(nat.match.if_index),
nat.match.min_address,
nat.match.max_address,
str(nat.match.min_port),
str(nat.match.max_port),
nat.target.if_type,
str(nat.target.if_index),
nat.target.min_address,
nat.target.max_address,
str(nat.target.min_port),
str(nat.target.max_port),
]
return args, constrains
def config_nat(nf_command, nat_type, router_id, rule_id, nat):
log.debug('nf_command: %s, nat_id: %r-%r, nat: %r' % (
nf_command, router_id, rule_id, nat.to_native()))
args, constrains = get_config_nat_args(nf_command, nat_type,
router_id, nat)
if constrains is not None:
log.info(constrains)
return json_response(
status=INVALID_POST_DATA, description=constrains
), HTTP_BAD_REQUEST
key = (nf_command, 'nat', nat_type, str(router_id), str(nat.rule_id))
ret_queue = PseudoGeventQueue()
cmd_waiting_queues_put(router_id,
router_hash,
key,
args,
ret_queue)
output = cmd_response_get(ret_queue)
if output:
return json_response(
status=SERVER_ERROR, description=output
), HTTP_INTERNAL_SERVER_ERROR
return json_response(status=SUCCESS), HTTP_OK