Skip to content

Commit 4e8d9b0

Browse files
authored
Merge pull request #210 from bcgov/dev
Feature upgrade deck (#203)
2 parents 2f7e5e2 + dcf33c2 commit 4e8d9b0

File tree

10 files changed

+199
-91
lines changed

10 files changed

+199
-91
lines changed

microservices/gatewayApi/Dockerfile

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ RUN curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -
2020

2121
#COPY --from=build /deck/deck /usr/local/bin
2222

23-
# gwa api v1/v2
23+
# gwa api (kong 2)
2424
RUN curl -sL https://github.com/kong/deck/releases/download/v1.5.0/deck_1.5.0_linux_amd64.tar.gz -o deck.tar.gz && \
2525
tar -xf deck.tar.gz -C /tmp && \
26-
cp /tmp/deck /usr/local/bin/
26+
cp /tmp/deck /usr/local/bin/deck_kong2_150
2727

28-
# gwa api v3
29-
RUN curl -sL https://github.com/Kong/deck/releases/download/v1.27.1/deck_1.27.1_linux_amd64.tar.gz -o deck.tar.gz && \
28+
# gwa api (kong 3)
29+
RUN curl -sL https://github.com/Kong/deck/releases/download/v1.45.0/deck_1.45.0_linux_amd64.tar.gz -o deck.tar.gz && \
3030
tar -xf deck.tar.gz -C /tmp && \
31-
cp /tmp/deck /usr/local/bin/deck127
31+
cp /tmp/deck /usr/local/bin/deck && \
32+
cp /tmp/deck /usr/local/bin/deck_kong3_1450
3233

3334
RUN python -m pip install --upgrade pip
3435
# FIX: No module named 'urllib3.packages.six'
@@ -50,5 +51,6 @@ RUN chmod +x entrypoint.sh
5051
EXPOSE 2000
5152

5253
ENV DECK_ANALYTICS=off
54+
ENV DECK_CLI=deck
5355

5456
ENTRYPOINT ["./entrypoint.sh"]

microservices/gatewayApi/config/test.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
"kubeApiPass": "password",
3131
"kubeApiUser": "username"
3232
},
33-
"compatibilityApiUrl": "http://compatibility-api"
33+
"compatibilityApiUrl": "http://compatibility-api",
34+
"deckCLI": "deck"
3435
}

microservices/gatewayApi/entrypoint.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ cat > "${CONFIG_PATH:-./config/default.json}" <<EOF
6161
"kubeApiUser": "${KUBE_API_USER}",
6262
"kubeApiPass": "${KUBE_API_PASS}"
6363
},
64-
"compatibilityApiUrl": "${COMPATIBILITY_API_URL}"
64+
"compatibilityApiUrl": "${COMPATIBILITY_API_URL}",
65+
"deckCLI": "${DECK_CLI}"
6566
}
6667
EOF
6768

microservices/gatewayApi/tests/routes/v2/test_gateway.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -168,37 +168,37 @@ def test_success_mtls_reference(client):
168168
assert response.status_code == 200
169169
assert json.dumps(response.json) == '{"message": "Sync successful.", "results": "Deck reported no changes"}'
170170

171-
def test_kong3_compatibility_warning(client):
172-
"""Test that Kong 3 incompatible config generates warning"""
173-
configFile = '''
174-
services:
175-
- name: my-service
176-
host: myupstream.local
177-
tags: ["ns.mytest", "another"]
178-
routes:
179-
- name: route-1
180-
hosts: [ myapi.api.gov.bc.ca ]
181-
paths: [ "/path*" ]
182-
tags: ["ns.mytest", "another2"]
183-
- name: route-2
184-
hosts: [ myapi2.api.gov.bc.ca ]
185-
paths: [ "/other*" ]
186-
tags: ["ns.mytest", "another2"]
187-
'''
188-
189-
data = {
190-
"configFile": configFile,
191-
"dryRun": False
192-
}
193-
response = client.put('/v2/namespaces/mytest/gateway', json=data)
194-
assert response.status_code == 200
195-
response_data = response.json
196-
assert response_data["message"] == "Sync successful."
171+
# def test_kong3_compatibility_warning(client):
172+
# """Test that Kong 3 incompatible config generates warning"""
173+
# configFile = '''
174+
# services:
175+
# - name: my-service
176+
# host: myupstream.local
177+
# tags: ["ns.mytest", "another"]
178+
# routes:
179+
# - name: route-1
180+
# hosts: [ myapi.api.gov.bc.ca ]
181+
# paths: [ "/path*" ]
182+
# tags: ["ns.mytest", "another2"]
183+
# - name: route-2
184+
# hosts: [ myapi2.api.gov.bc.ca ]
185+
# paths: [ "/other*" ]
186+
# tags: ["ns.mytest", "another2"]
187+
# '''
188+
189+
# data = {
190+
# "configFile": configFile,
191+
# "dryRun": False
192+
# }
193+
# response = client.put('/v2/namespaces/mytest/gateway', json=data)
194+
# assert response.status_code == 200
195+
# response_data = response.json
196+
# assert response_data["message"] == "Sync successful."
197197

198-
# Verify warning message and failed routes are in results
199-
results = response_data["results"]
200-
assert "Kong 3 incompatible routes found" in results
201-
assert "route-1" in results
202-
assert "route-2" in results
203-
# Routes should only be listed once even if multiple incompatible paths
204-
assert results.count("route-1") == 1
198+
# # Verify warning message and failed routes are in results
199+
# results = response_data["results"]
200+
# assert "Kong 3 incompatible routes found" in results
201+
# assert "route-1" in results
202+
# assert "route-2" in results
203+
# # Routes should only be listed once even if multiple incompatible paths
204+
# assert results.count("route-1") == 1
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
2+
3+
from utils.transforms import add_version_if_missing
4+
import yaml
5+
6+
def test_add_version_with_format():
7+
payload = '''
8+
_format_version: '3.0'
9+
services:
10+
- host: myservice
11+
name: my-service
12+
tags:
13+
- ns.mytest
14+
- another
15+
'''
16+
y = yaml.load(payload, Loader=yaml.FullLoader)
17+
18+
add_version_if_missing(y)
19+
20+
result = yaml.dump(y, indent=2)
21+
22+
assert payload.strip() == result.strip()
23+
24+
def test_add_version_if_missing():
25+
payload = '''
26+
services:
27+
- host: myservice
28+
name: my-service
29+
tags:
30+
- ns.mytest
31+
- another
32+
'''
33+
34+
expected = '''
35+
_format_version: '3.0'
36+
services:
37+
- host: myservice
38+
name: my-service
39+
tags:
40+
- ns.mytest
41+
- another
42+
'''
43+
y = yaml.load(payload, Loader=yaml.FullLoader)
44+
45+
add_version_if_missing(y)
46+
47+
result = yaml.dump(y, indent=2)
48+
49+
assert expected.strip() == result.strip()
50+
51+
52+
def test_add_version_with_v1():
53+
payload = '''
54+
_format_version: 1.0
55+
services:
56+
- host: myservice
57+
name: my-service
58+
tags:
59+
- ns.mytest
60+
- another
61+
'''
62+
63+
expected = '''
64+
_format_version: '3.0'
65+
services:
66+
- host: myservice
67+
name: my-service
68+
tags:
69+
- ns.mytest
70+
- another
71+
'''
72+
y = yaml.load(payload, Loader=yaml.FullLoader)
73+
74+
add_version_if_missing(y)
75+
76+
result = yaml.dump(y, indent=2)
77+
78+
assert expected.strip() == result.strip()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
def deck_cmd_sync_diff(deck_cli, cmd, select_tag, state):
3+
if deck_cli == "deck" or deck_cli.startswith("deck_kong3_"):
4+
return [ deck_cli, "gateway", cmd, "--config", "/tmp/deck.yaml", "--skip-consumers", "--select-tag", select_tag, state]
5+
else:
6+
return [ deck_cli, cmd, "--config", "/tmp/deck.yaml", "--skip-consumers", "--select-tag", select_tag, "--state", state]
7+
8+
def deck_cmd_validate(deck_cli, state):
9+
if deck_cli == "deck" or deck_cli.startswith("deck_kong3_"):
10+
return [ deck_cli, "gateway", "validate", "--config", "/tmp/deck.yaml", state ]
11+
else:
12+
return [ deck_cli, "validate", "--config", "/tmp/deck.yaml", "--state", state ]

microservices/gatewayApi/utils/transforms.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,6 @@ def traverse_plugins (yaml, plugin_configs = None):
9494
upstream_jwt(item, plugin_configs)
9595
traverse_plugins (item, plugin_configs)
9696

97-
98-
97+
def add_version_if_missing(yaml):
98+
if "_format_version" not in yaml or yaml["_format_version"] != "3.0":
99+
yaml["_format_version"] = "3.0"

microservices/gatewayApi/v1/routes/gateway.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
from clients.ocp_gateway_secret import prep_submitted_config, prep_and_apply_secret, write_submitted_config
2727

2828
from utils.validators import host_valid, validate_upstream
29-
from utils.transforms import plugins_transformations
29+
from utils.transforms import plugins_transformations, add_version_if_missing
3030
from utils.masking import mask
31+
from utils.deck import deck_cmd_sync_diff, deck_cmd_validate
3132

3233
gw = Blueprint('gwa', 'gateway')
3334

@@ -67,11 +68,12 @@ def delete_config(namespace: str, qualifier="") -> object:
6768

6869
# Call the 'deck' command
6970
cmd = "sync"
71+
deck_cli = app.config['deckCLI']
72+
73+
74+
log.info("[%s] (%s) %s action using %s" % (namespace, deck_cli, cmd, selectTag))
75+
args = deck_cmd_sync_diff(deck_cli, cmd, selectTag, tempFolder)
7076

71-
log.info("[%s] %s action using %s" % (namespace, cmd, selectTag))
72-
args = [
73-
"deck", cmd, "--config", "/tmp/deck.yaml", "--skip-consumers", "--select-tag", selectTag, "--state", tempFolder
74-
]
7577
log.debug("[%s] Running %s" % (namespace, args))
7678
deck_run = Popen(args, stdout=PIPE, stderr=STDOUT)
7779
out, err = deck_run.communicate()
@@ -235,6 +237,9 @@ def write_config(namespace: str) -> object:
235237
# Enrichments
236238
#######################
237239

240+
# Add format version if its missing - needed in Kong v3+
241+
add_version_if_missing(gw_config)
242+
238243
# Transformation route hosts if in non-prod environment (HOST_TRANSFORM_ENABLED)
239244
host_transformation(namespace, gw_config)
240245

@@ -246,19 +251,21 @@ def write_config(namespace: str) -> object:
246251
# Enrich the rate-limiting plugin with the appropriate Redis details
247252
plugins_transformations(namespace, gw_config)
248253

249-
# Check Kong 3 compatibility
250-
is_compatible, compatibility_message, failed_routes, kong2_config = check_kong3_compatibility(namespace, gw_config)
251-
if not is_compatible:
252-
warning_message = compatibility_message
254+
# Disabled:
255+
#
256+
# # Check Kong 3 compatibility
257+
# is_compatible, compatibility_message, failed_routes, kong2_config = check_kong3_compatibility(namespace, gw_config)
258+
# if not is_compatible:
259+
# warning_message = compatibility_message
253260

254-
# Track incompatible routes
255-
if not is_compatible:
256-
has_incompatible_routes = True
257-
all_failed_routes.extend(failed_routes)
261+
# # Track incompatible routes
262+
# if not is_compatible:
263+
# has_incompatible_routes = True
264+
# all_failed_routes.extend(failed_routes)
258265

259-
# Use kong2_config (which has compatibility tags) regardless of compatibility status
260-
if kong2_config:
261-
gw_config = kong2_config
266+
# # Use kong2_config (which has compatibility tags) regardless of compatibility status
267+
# if kong2_config:
268+
# gw_config = kong2_config
262269

263270
with open("%s/%s" % (tempFolder, 'config-%02d.yaml' % index), 'w') as file:
264271
yaml.dump(gw_config, file)
@@ -320,12 +327,12 @@ def write_config(namespace: str) -> object:
320327
selectTag = ns_qualifier
321328

322329
# Call the 'deck' command
330+
deck_cli = app.config['deckCLI']
331+
332+
log.info("[%s] (%s) %s action using %s" % (namespace, deck_cli, cmd, selectTag))
323333

324-
log.info("[%s] %s action using %s" % (namespace, cmd, selectTag))
334+
args = deck_cmd_validate(deck_cli, tempFolder)
325335

326-
args = [
327-
"deck", "validate", "--config", "/tmp/deck.yaml", "--state", tempFolder
328-
]
329336
log.debug("[%s] Running %s" % (namespace, args))
330337
deck_validate = Popen(args, stdout=PIPE, stderr=STDOUT)
331338
out, err = deck_validate.communicate()
@@ -335,9 +342,8 @@ def write_config(namespace: str) -> object:
335342
abort_early(event_id, 'validate', namespace, jsonify(
336343
error="Validation Failed.", results=mask(out.decode('utf-8'))))
337344

338-
args = [
339-
"deck", cmd, "--config", "/tmp/deck.yaml", "--skip-consumers", "--select-tag", selectTag, "--state", tempFolder
340-
]
345+
args = deck_cmd_sync_diff(deck_cli, cmd, selectTag, tempFolder)
346+
341347
log.debug("[%s] Running %s" % (namespace, args))
342348
deck_run = Popen(args, stdout=PIPE, stderr=STDOUT)
343349
out, err = deck_run.communicate()

0 commit comments

Comments
 (0)