unsupported 부분 수정
This commit is contained in:
15
mapping.yaml
15
mapping.yaml
@@ -71,7 +71,22 @@ nginx.ingress.kubernetes.io/enable-cors:
|
|||||||
haproxy: haproxy.org/enable-cors
|
haproxy: haproxy.org/enable-cors
|
||||||
support: full
|
support: full
|
||||||
|
|
||||||
|
nginx.ingress.kubernetes.io/app-root:
|
||||||
|
haproxy: haproxy.org/path-rewrite
|
||||||
|
support: partial
|
||||||
|
note: "Chage Value"
|
||||||
|
|
||||||
nginx.ingress.kubernetes.io/configuration-snippet:
|
nginx.ingress.kubernetes.io/configuration-snippet:
|
||||||
haproxy: null
|
haproxy: null
|
||||||
support: unsupported
|
support: unsupported
|
||||||
note: "HAProxy does not support arbitrary NGINX snippets"
|
note: "HAProxy does not support arbitrary NGINX snippets"
|
||||||
|
|
||||||
|
proxy-buffering:
|
||||||
|
haproxy: null
|
||||||
|
support: unsupported
|
||||||
|
note: "HAProxy does not support arbitrary NGINX snippets"
|
||||||
|
|
||||||
|
gzip-level:
|
||||||
|
haproxy: null
|
||||||
|
support: unspported
|
||||||
|
note: "HAProxy does not support arbitrary NGINX snippets"
|
||||||
|
|||||||
198
migrate.py
198
migrate.py
@@ -15,6 +15,7 @@ from ruamel.yaml.comments import CommentedMap
|
|||||||
yaml = YAML()
|
yaml = YAML()
|
||||||
yaml.preserve_quotes = True
|
yaml.preserve_quotes = True
|
||||||
yaml.indent(mapping=2, sequence=4, offset=2)
|
yaml.indent(mapping=2, sequence=4, offset=2)
|
||||||
|
yaml.width = 4096
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -35,6 +36,34 @@ def load_mapping(path):
|
|||||||
return yaml.load(f)
|
return yaml.load(f)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# annotation 렌더링
|
||||||
|
# -----------------------------
|
||||||
|
def render_annotations_block(unsupported, partial, converted):
|
||||||
|
"""
|
||||||
|
annotations 하위에 그대로 삽입될 문자열을 생성
|
||||||
|
"""
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
if unsupported:
|
||||||
|
note = unsupported[0]["note"]
|
||||||
|
lines.append(f" # {note}")
|
||||||
|
for u in unsupported:
|
||||||
|
lines.append(f" #{u['key']}: {u['value']}")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
if partial:
|
||||||
|
for p in partial:
|
||||||
|
lines.append(f" # PARTIAL SUPPORT: {p['note']}")
|
||||||
|
lines.append(f" {p['haproxy']}: {p['value']}")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
for c in converted:
|
||||||
|
lines.append(f" {c['haproxy']}: {c['value']}")
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# ingress 변환 로직
|
# ingress 변환 로직
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -60,51 +89,48 @@ def migrate_ingress(data, mapping, ingress_class=None):
|
|||||||
spec["ingressClassName"] = ingress_class
|
spec["ingressClassName"] = ingress_class
|
||||||
|
|
||||||
anns = meta.get("annotations", {}) or {}
|
anns = meta.get("annotations", {}) or {}
|
||||||
new_anns = CommentedMap()
|
|
||||||
|
unsupported = []
|
||||||
|
partial = []
|
||||||
|
converted = []
|
||||||
|
|
||||||
for k, v in anns.items():
|
for k, v in anns.items():
|
||||||
if k in mapping:
|
rule = mapping.get(k)
|
||||||
rule = mapping[k]
|
|
||||||
support = rule.get("support", "unsupported")
|
|
||||||
haproxy_key = rule.get("haproxy")
|
|
||||||
|
|
||||||
if support == "full":
|
if not rule:
|
||||||
new_anns[haproxy_key] = v
|
converted.append({"haproxy": k, "value": v})
|
||||||
report["converted"].append(k)
|
continue
|
||||||
|
|
||||||
elif support == "partial":
|
support = rule.get("support", "unsupported")
|
||||||
new_anns[haproxy_key] = v
|
haproxy_key = rule.get("haproxy")
|
||||||
note = rule.get("note", "")
|
note = rule.get("note", "no HAProxy equivalent")
|
||||||
new_anns.yaml_set_comment_before_after_key(
|
|
||||||
haproxy_key,
|
|
||||||
before=f"PARTIAL SUPPORT: {note}",
|
|
||||||
)
|
|
||||||
report["partial"].append(k)
|
|
||||||
report["detail"][ingress_id]["partial"].append(
|
|
||||||
{
|
|
||||||
"nginx": k,
|
|
||||||
"haproxy": haproxy_key,
|
|
||||||
"note": note,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
if support == "full" and haproxy_key:
|
||||||
lines = [f"UNSUPPORTED {k}:"]
|
converted.append({"haproxy": haproxy_key, "value": v})
|
||||||
for line in str(v).splitlines():
|
report["converted"].append(k)
|
||||||
lines.append(f" {line}")
|
|
||||||
new_anns.yaml_set_end_comment("\n".join(lines))
|
elif support == "partial" and haproxy_key:
|
||||||
|
partial.append(
|
||||||
|
{"haproxy": haproxy_key, "value": v, "note": note}
|
||||||
|
)
|
||||||
|
report["partial"].append(k)
|
||||||
|
report["detail"][ingress_id]["partial"].append(
|
||||||
|
{"nginx": k, "haproxy": haproxy_key, "note": note}
|
||||||
|
)
|
||||||
|
|
||||||
report["unsupported"].append(k)
|
|
||||||
report["detail"][ingress_id]["unsupported"].append(
|
|
||||||
{
|
|
||||||
"nginx": k,
|
|
||||||
"value": v,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
new_anns[k] = v
|
unsupported.append(
|
||||||
|
{"key": k, "value": v, "note": note}
|
||||||
|
)
|
||||||
|
report["unsupported"].append(k)
|
||||||
|
report["detail"][ingress_id]["unsupported"].append(
|
||||||
|
{"nginx": k, "value": v, "note": note}
|
||||||
|
)
|
||||||
|
|
||||||
meta["annotations"] = new_anns
|
meta["annotations"] = CommentedMap()
|
||||||
|
item["_rendered_annotations"] = render_annotations_block(
|
||||||
|
unsupported, partial, converted
|
||||||
|
)
|
||||||
|
|
||||||
return new, report
|
return new, report
|
||||||
|
|
||||||
@@ -121,51 +147,78 @@ def write_report(report, path):
|
|||||||
f.write(f"- Unsupported: {len(report['unsupported'])}\n\n")
|
f.write(f"- Unsupported: {len(report['unsupported'])}\n\n")
|
||||||
f.write("---\n\n")
|
f.write("---\n\n")
|
||||||
|
|
||||||
if any(v["partial"] for v in report["detail"].values()):
|
for ingress, detail in report["detail"].items():
|
||||||
f.write("## ⚠️ Partial Support\n\n")
|
if not detail["partial"] and not detail["unsupported"]:
|
||||||
for ingress, items in report["detail"].items():
|
continue
|
||||||
if not items["partial"]:
|
|
||||||
continue
|
|
||||||
f.write(f"### {ingress}\n")
|
|
||||||
for p in items["partial"]:
|
|
||||||
f.write(
|
|
||||||
f"- {p['nginx']}\n"
|
|
||||||
f" - mapped to: {p['haproxy']}\n"
|
|
||||||
f" - note: {p['note']}\n"
|
|
||||||
)
|
|
||||||
f.write("\n")
|
|
||||||
|
|
||||||
if any(v["unsupported"] for v in report["detail"].values()):
|
f.write(f"## {ingress}\n\n")
|
||||||
f.write("## ❌ Unsupported\n\n")
|
|
||||||
for ingress, items in report["detail"].items():
|
for p in detail["partial"]:
|
||||||
if not items["unsupported"]:
|
f.write(
|
||||||
continue
|
f"- PARTIAL {p['nginx']} → {p['haproxy']}\n"
|
||||||
f.write(f"### {ingress}\n")
|
f" - note: {p['note']}\n"
|
||||||
for u in items["unsupported"]:
|
)
|
||||||
f.write(f"- {u['nginx']}\n")
|
|
||||||
f.write(" ```nginx\n")
|
for u in detail["unsupported"]:
|
||||||
f.write(f"{u['value']}\n")
|
f.write(
|
||||||
f.write(" ```\n")
|
f"- UNSUPPORTED {u['nginx']}\n"
|
||||||
f.write("\n")
|
f" - note: {u['note']}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
f.write("\n")
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# 파일 저장
|
# 파일 저장 (split)
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
def save_single(data, out_path):
|
|
||||||
with open(out_path, "w") as f:
|
|
||||||
yaml.dump(data, f)
|
|
||||||
|
|
||||||
|
|
||||||
def save_split(data, out_dir):
|
def save_split(data, out_dir):
|
||||||
Path(out_dir).mkdir(parents=True, exist_ok=True)
|
Path(out_dir).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
for item in data.get("items", []):
|
for item in data.get("items", []):
|
||||||
|
rendered = item.pop("_rendered_annotations", "")
|
||||||
name = item["metadata"]["name"]
|
name = item["metadata"]["name"]
|
||||||
namespace = item["metadata"].get("namespace", "default")
|
namespace = item["metadata"].get("namespace", "default")
|
||||||
path = Path(out_dir) / f"{namespace}__{name}.yaml"
|
path = Path(out_dir) / f"{namespace}__{name}.yaml"
|
||||||
|
|
||||||
with open(path, "w") as f:
|
with open(path, "w") as f:
|
||||||
yaml.dump(item, f)
|
yaml.dump(item, f)
|
||||||
|
|
||||||
|
if rendered:
|
||||||
|
content = path.read_text()
|
||||||
|
content = content.replace(
|
||||||
|
"metadata:\n",
|
||||||
|
"metadata:\n annotations:\n" + rendered + "\n",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
path.write_text(content)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# 파일 저장 (single)
|
||||||
|
# -----------------------------
|
||||||
|
def save_single(data, out_path):
|
||||||
|
rendered_map = {}
|
||||||
|
|
||||||
|
for item in data.get("items", []):
|
||||||
|
rendered_map[id(item)] = item.pop("_rendered_annotations", "")
|
||||||
|
|
||||||
|
path = Path(out_path)
|
||||||
|
with path.open("w") as f:
|
||||||
|
yaml.dump(data, f)
|
||||||
|
|
||||||
|
content = path.read_text()
|
||||||
|
|
||||||
|
for item in data.get("items", []):
|
||||||
|
rendered = rendered_map.get(id(item))
|
||||||
|
if rendered:
|
||||||
|
content = content.replace(
|
||||||
|
"metadata:\n",
|
||||||
|
"metadata:\n annotations:\n" + rendered + "\n",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
path.write_text(content)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# main
|
# main
|
||||||
@@ -180,9 +233,7 @@ def main():
|
|||||||
parser.add_argument("--out", default="output")
|
parser.add_argument("--out", default="output")
|
||||||
parser.add_argument("--ingress-class")
|
parser.add_argument("--ingress-class")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--report",
|
"--report", default="migration-report.md"
|
||||||
default="migration-report.md",
|
|
||||||
help="migration summary report file",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
@@ -194,9 +245,7 @@ def main():
|
|||||||
mapping = load_mapping(args.mapping)
|
mapping = load_mapping(args.mapping)
|
||||||
|
|
||||||
converted, report = migrate_ingress(
|
converted, report = migrate_ingress(
|
||||||
ingress,
|
ingress, mapping, ingress_class=args.ingress_class
|
||||||
mapping,
|
|
||||||
ingress_class=args.ingress_class,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if args.single:
|
if args.single:
|
||||||
@@ -217,3 +266,4 @@ def main():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user