diff --git a/.gitignore b/.gitignore
index 6fad0508..6e122242 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,6 @@ vendor/*
teams/*
teamcreds.txt
lib/harbor/certs/*
+sam/
+work.txt
+sam.yml
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 344ddf7a..bf5bc083 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,5 +1,2 @@
-[submodule "katana-services"]
- path = katana-services
- url = git@github.com:sdslabs/katana-services.git
[submodule "git@github.com:sdslabs/katana-services.git"]
branch = main
diff --git a/challenge_template/knock/flag-data/knock/knock-flag-getter.txt b/challenge_template/knock/flag-data/knock/knock-flag-getter.txt
deleted file mode 100644
index 34ebd7c1..00000000
--- a/challenge_template/knock/flag-data/knock/knock-flag-getter.txt
+++ /dev/null
@@ -1 +0,0 @@
-knock flag getter
\ No newline at end of file
diff --git a/challenge_template/knock/flag-data/knock/knock-flag-setter.txt b/challenge_template/knock/flag-data/knock/knock-flag-setter.txt
deleted file mode 100644
index d28196c1..00000000
--- a/challenge_template/knock/flag-data/knock/knock-flag-setter.txt
+++ /dev/null
@@ -1 +0,0 @@
-knock flag setter
\ No newline at end of file
diff --git a/challenge_template/knock/knock-challenge-checker/knock-challenge-checker.txt b/challenge_template/knock/knock-challenge-checker/knock-challenge-checker.txt
deleted file mode 100644
index 81bc6bc4..00000000
--- a/challenge_template/knock/knock-challenge-checker/knock-challenge-checker.txt
+++ /dev/null
@@ -1 +0,0 @@
-knock challenge checker
\ No newline at end of file
diff --git a/challenge_template/knock/knock.tar.gz b/challenge_template/knock/knock.tar.gz
deleted file mode 100644
index 2895b7f4..00000000
Binary files a/challenge_template/knock/knock.tar.gz and /dev/null differ
diff --git a/challenges-sample/knock/challenge-checker/Dockerfile b/challenges-sample/knock/challenge-checker/Dockerfile
new file mode 100644
index 00000000..e9273436
--- /dev/null
+++ b/challenges-sample/knock/challenge-checker/Dockerfile
@@ -0,0 +1,11 @@
+FROM ubuntu:20.04
+
+RUN apt-get update
+RUN apt-get install -y python3 python3-pip curl
+
+WORKDIR /opt/kissaki/
+COPY . .
+
+RUN pip3 install -r requirements.txt
+
+CMD ["/bin/bash", "-c", "python3 /opt/kissaki/app.py" ]
diff --git a/challenges-sample/knock/challenge-checker/app.py b/challenges-sample/knock/challenge-checker/app.py
new file mode 100644
index 00000000..9d6c80a4
--- /dev/null
+++ b/challenges-sample/knock/challenge-checker/app.py
@@ -0,0 +1,94 @@
+import requests
+import time
+from flask import Flask, jsonify
+import os
+from kubernetes import client, config
+import logging
+
+# app = Flask(__name__)
+
+# Set up logging
+logging.basicConfig(level=logging.INFO)
+
+try:
+ config.load_incluster_config()
+except config.config_exception.ConfigException:
+ try:
+ config.load_kube_config()
+ except config.config_exception.ConfigException:
+ raise
+
+v1 = client.CoreV1Api()
+service = v1.read_namespaced_service(name="kissaki-svc", namespace="katana")
+cluster_ip = service.spec.cluster_ip
+ports = service.spec.ports
+port = ports[0].port
+
+
+# @app.route("/")
+def hello():
+ return "Hello, world!"
+
+
+# @app.route("/test")
+def test_challenge_checker():
+ res = (
+ "making request to "
+ + "http://"
+ + str(cluster_ip)
+ + ":"
+ + str(port)
+ + "/register "
+ )
+ return res
+
+
+# @app.route("/register")
+def register_challenge_checker():
+ logging.info(
+ "making request to "
+ + "http://"
+ + str(cluster_ip)
+ + ":"
+ + str(port)
+ + "/register "
+ )
+
+ # Register with kissaki
+ checker_info = {
+ "name": "knock-challenge-checker",
+ "challenge": "knock",
+ } # Example info
+
+ response = requests.post(
+ "http://" + str(cluster_ip) + ":" + str(port) + "/register",
+ json=checker_info,
+ )
+ message = response.json().get("message")
+
+ logging.info(f"Received message from kissaki: {message}")
+
+ return "challenge_checker registered in kissaki"
+
+
+# @app.route("/check")
+def check_challenge():
+ for i in range(10):
+ # TODO: Implement challenge checking logic
+ challenge_status = {"status": "OK"} # Example status
+
+ # Send status to kissaki service
+ response = requests.post(
+ "http://" + str(cluster_ip) + ":" + str(port) + "/status",
+ json=challenge_status,
+ )
+ message = response.json().get("message")
+ logging.info(f"Received message from kissaki: {message}")
+
+ time.sleep(10) # Check every 10 seconds
+
+ return jsonify(challenge_status)
+
+
+# if __name__ == "__main__":
+# app.run(host="0.0.0.0", port=8080)
diff --git a/challenges-sample/knock/challenge-checker/challenge-checker.txt b/challenges-sample/knock/challenge-checker/challenge-checker.txt
new file mode 100644
index 00000000..cc4198f5
--- /dev/null
+++ b/challenges-sample/knock/challenge-checker/challenge-checker.txt
@@ -0,0 +1 @@
+challenge checker
\ No newline at end of file
diff --git a/challenges-sample/knock/challenge-checker/requirements.txt b/challenges-sample/knock/challenge-checker/requirements.txt
new file mode 100644
index 00000000..afdcb62e
--- /dev/null
+++ b/challenges-sample/knock/challenge-checker/requirements.txt
@@ -0,0 +1,3 @@
+kubernetes
+flask
+requests
\ No newline at end of file
diff --git a/challenges-sample/knock/challenge-checker/scheduler.txt b/challenges-sample/knock/challenge-checker/scheduler.txt
new file mode 100644
index 00000000..fb158aef
--- /dev/null
+++ b/challenges-sample/knock/challenge-checker/scheduler.txt
@@ -0,0 +1 @@
+contains informations about schedules
\ No newline at end of file
diff --git a/challenge_template/knock/knock/knock/Dockerfile b/challenges-sample/knock/challenge/Dockerfile
similarity index 100%
rename from challenge_template/knock/knock/knock/Dockerfile
rename to challenges-sample/knock/challenge/Dockerfile
diff --git a/challenge_template/knock/knock/knock/challenge.yaml b/challenges-sample/knock/challenge/challenge.yaml
similarity index 100%
rename from challenge_template/knock/knock/knock/challenge.yaml
rename to challenges-sample/knock/challenge/challenge.yaml
diff --git a/challenge_template/knock/knock/knock/index.js b/challenges-sample/knock/challenge/index.js
similarity index 100%
rename from challenge_template/knock/knock/knock/index.js
rename to challenges-sample/knock/challenge/index.js
diff --git a/challenge_template/knock/knock/knock/package.json b/challenges-sample/knock/challenge/package.json
similarity index 100%
rename from challenge_template/knock/knock/knock/package.json
rename to challenges-sample/knock/challenge/package.json
diff --git a/challenge_template/knock/knock/knock/public/index.html b/challenges-sample/knock/challenge/public/index.html
similarity index 100%
rename from challenge_template/knock/knock/knock/public/index.html
rename to challenges-sample/knock/challenge/public/index.html
diff --git a/challenge_template/knock/knock/knock/yarn.lock b/challenges-sample/knock/challenge/yarn.lock
similarity index 100%
rename from challenge_template/knock/knock/knock/yarn.lock
rename to challenges-sample/knock/challenge/yarn.lock
diff --git a/challenges-sample/knock/flag-handler/flag-getter.txt b/challenges-sample/knock/flag-handler/flag-getter.txt
new file mode 100644
index 00000000..d8fedfb4
--- /dev/null
+++ b/challenges-sample/knock/flag-handler/flag-getter.txt
@@ -0,0 +1 @@
+flag getter
\ No newline at end of file
diff --git a/challenges-sample/knock/flag-handler/flag-setter.txt b/challenges-sample/knock/flag-handler/flag-setter.txt
new file mode 100644
index 00000000..df42dade
--- /dev/null
+++ b/challenges-sample/knock/flag-handler/flag-setter.txt
@@ -0,0 +1 @@
+flag setter
\ No newline at end of file
diff --git a/challenges-sample/knock/katana.toml b/challenges-sample/knock/katana.toml
new file mode 100644
index 00000000..f34742d0
--- /dev/null
+++ b/challenges-sample/knock/katana.toml
@@ -0,0 +1,13 @@
+[challenge.author]
+name = "paradox"
+email = "paradox@katana.local"
+
+[challenge.metadata]
+name = "knock"
+flag = "dice{1_d00r_y0u_d00r_w3_a11_d00r_f0r_1_d00r}"
+description = "Knock knock? Who's there? Another pastebin!!"
+type = "web"
+points = 100
+
+[challenge.env]
+port_mappings = ["3000:3000"]
\ No newline at end of file
diff --git a/challenges-sample/the-varsity/challenge-checker/Dockerfile b/challenges-sample/the-varsity/challenge-checker/Dockerfile
new file mode 100644
index 00000000..e81d04aa
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge-checker/Dockerfile
@@ -0,0 +1,15 @@
+FROM ubuntu:20.04
+
+RUN apt-get update
+RUN apt-get install -y python3 python3-pip curl
+
+WORKDIR /opt/kissaki/
+COPY . .
+
+RUN pip3 install -r requirements.txt
+
+# this arg is not being passed need to fix that.------------------------
+ARG chall_name
+ENV CHALL_NAME=$chall_name
+
+CMD ["/bin/bash", "-c", "python3 /opt/kissaki/app.py" ]
diff --git a/challenges-sample/the-varsity/challenge-checker/app.py b/challenges-sample/the-varsity/challenge-checker/app.py
new file mode 100644
index 00000000..d778f970
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge-checker/app.py
@@ -0,0 +1,167 @@
+import requests
+import time
+from flask import Flask, jsonify
+import os
+from kubernetes import client, config
+import logging
+
+import chall_checker # import the module containing the script
+
+app = Flask(__name__)
+
+
+chall_name = os.environ.get("CHALL_NAME")
+chall_name = chall_name[:-3]
+chall_name = "the-varsity" # fix this later
+# kissaki
+svc_name = "kissaki-svc"
+namespace = "katana"
+team_count = 2 # ----------harcoded for now, need to fix this
+# Set up logging
+logging.basicConfig(level=logging.INFO)
+
+try:
+ config.load_incluster_config()
+except config.config_exception.ConfigException:
+ try:
+ config.load_kube_config()
+ except config.config_exception.ConfigException:
+ raise
+
+# v1 = client.CoreV1Api()
+# service = v1.read_namespaced_service(name=svc_name, namespace=namespace)
+# # cluster_ip = service.spec.cluster_ip
+# ports = service.spec.ports
+# port = ports[0].port
+
+v1 = client.CoreV1Api()
+
+
+def service_port(svc, ns):
+ service = v1.read_namespaced_service(name=svc, namespace=ns)
+ # cluster_ip = service.spec.cluster_ip
+ ports = service.spec.ports
+ port = ports[0].port
+ return port
+
+
+@app.route("/")
+def hello():
+ logging.info(chall_name)
+ return "Hello, world!"
+
+
+@app.route("/test")
+def test_challenge_checker():
+ res = (
+ "making request to "
+ + "http://"
+ + svc_name
+ + "."
+ + namespace
+ + ".svc.cluster.local:"
+ + str(service_port(svc_name, namespace))
+ + "/register "
+ )
+ return res
+
+
+# @app.route("/register")
+# def register_challenge_checker():
+# logging.info(
+# "making request to "
+# + "http://"
+# + str(cluster_ip)
+# + ":"
+# + str(port)
+# + "/register "
+# )
+
+# # Register with kissaki
+# checker_info = {
+# "name": "knock-challenge-checker",
+# "challenge": "knock",
+# } # Example info
+
+# response = requests.post(
+# "http://" + str(cluster_ip) + ":" + str(port) + "/register",
+# json=checker_info,
+# )
+# message = response.json().get("message")
+
+# logging.info(f"Received message from kissaki: {message}")
+
+# return "challenge_checker registered in kissaki"
+
+
+@app.route("/register")
+def register_challenge_checker():
+ logging.info(
+ "making request to "
+ + "http://"
+ + svc_name
+ + "."
+ + namespace
+ + ".svc.cluster.local:"
+ + str(service_port(svc_name, namespace))
+ + "/register "
+ )
+
+ # Register with kissaki
+ # keys in checker_info are harcoded if changed here then some change may be needed in katana-services/Kissaki/src/app.py
+ checker_info = {"ccName": chall_name + "-cc"}
+
+ response = requests.post(
+ "http://"
+ + svc_name
+ + "."
+ + namespace
+ + ".svc.cluster.local:"
+ + str(service_port(svc_name, namespace))
+ + "/register",
+ json=checker_info,
+ )
+ message = response.json().get("message")
+
+ logging.info(f"Received message from kissaki: {message}")
+
+ return "challenge_checker registered in kissaki"
+
+
+# {service_port(chall_svc, chall_ns)}
+@app.route("/check")
+def check_challenge():
+ i = 0
+ chall_svc = f"{chall_name}-svc-{i}"
+ chall_ns = f"katana-team-{i}-ns"
+ url = f"http://{chall_svc}.{chall_ns}.svc.cluster.local:80/"
+ return url
+ try:
+ status = chall_checker.check_challenge(url)
+ return status
+ except Exception as e:
+ logging.error(f"Error checking challenge: {str(e)}")
+ return str(e)
+
+
+@app.route("/checker")
+def check_route():
+ results = {"challengeName": chall_name, "data": []}
+ for i in range(team_count):
+ team_name = f"katana-team-{i}"
+ result = {"team-name": team_name}
+ chall_svc = f"{chall_name}-svc-{i}"
+ chall_ns = f"katana-team-{i}-ns"
+ url = f"http://{chall_svc}.{chall_ns}.svc.cluster.local:80/" # update this later ---port should not be hardcoded----
+ try:
+ status = chall_checker.check_challenge(url)
+ result["status"] = status
+ except Exception as e:
+ logging.error(f"Error checking challenge: {str(e)}")
+ result["error"] = str(e)
+ results["data"].append(result)
+ return jsonify(results)
+
+
+if __name__ == "__main__":
+ app.run(host="0.0.0.0", port=8080)
diff --git a/challenges-sample/the-varsity/challenge-checker/chall_checker.py b/challenges-sample/the-varsity/challenge-checker/chall_checker.py
new file mode 100644
index 00000000..dfb402ba
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge-checker/chall_checker.py
@@ -0,0 +1,54 @@
+import requests
+
+
+# if anything goes wrong then returns 0 at that instant otherwise returns 1 at last
+def check_challenge(url):
+ result = {}
+
+ register_response = requests.post(
+ url + "register", json={"username": "something", "voucher": ""}
+ )
+
+ # Check if the request was successful (status code 200)
+ if register_response.status_code == 200:
+ # Extract the value of the 'token' cookie
+ token_cookie = register_response.cookies.get("token")
+
+ # Print or use the token as needed
+ result["Token Cookie"] = token_cookie
+ else:
+ result["Request failed with status code"] = register_response.status_code
+ result["Response body"] = register_response.text
+ return 0
+
+ article_headers = {
+ "Accept": "*/*",
+ "Connection": "keep-alive",
+ "Content-Type": "application/json",
+ "Cookie": f"token={token_cookie}",
+ }
+
+ article_data = {"issue": "5"}
+
+ article_response = requests.post(
+ url + "article", json=article_data, headers=article_headers
+ )
+
+ if article_response.status_code == 200:
+ result["Article response"] = article_response.text
+ # print("Article response:", article_response.text)
+ else:
+ return 0
+
+ # exploit ------ not needed -------
+
+ # exploit = {"issue": "9a"}
+
+ # exploit_response = requests.post(
+ # url + "article", json=exploit, headers=article_headers
+ # )
+ # if exploit_response.status_code == 200:
+ # result["Exploit response"] = exploit_response.text
+ # result["Flag"] = exploit_response.json()["content"]
+
+ return 1
diff --git a/challenges-sample/the-varsity/challenge-checker/challenge-checker.txt b/challenges-sample/the-varsity/challenge-checker/challenge-checker.txt
new file mode 100644
index 00000000..cc4198f5
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge-checker/challenge-checker.txt
@@ -0,0 +1 @@
+challenge checker
\ No newline at end of file
diff --git a/challenges-sample/the-varsity/challenge-checker/requirements.txt b/challenges-sample/the-varsity/challenge-checker/requirements.txt
new file mode 100644
index 00000000..afdcb62e
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge-checker/requirements.txt
@@ -0,0 +1,3 @@
+kubernetes
+flask
+requests
\ No newline at end of file
diff --git a/challenges-sample/the-varsity/challenge-checker/scheduler.txt b/challenges-sample/the-varsity/challenge-checker/scheduler.txt
new file mode 100644
index 00000000..fb158aef
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge-checker/scheduler.txt
@@ -0,0 +1 @@
+contains informations about schedules
\ No newline at end of file
diff --git a/challenges-sample/the-varsity/challenge/Dockerfile b/challenges-sample/the-varsity/challenge/Dockerfile
new file mode 100644
index 00000000..b5df9a54
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/Dockerfile
@@ -0,0 +1,15 @@
+FROM node:20-bullseye-slim
+
+WORKDIR /usr/src/app
+
+ENV FLAG=uoftctf{this_is_a_fake_flag}
+
+COPY package*.json ./
+
+RUN npm install
+
+COPY . .
+
+EXPOSE 3000
+
+CMD [ "node", "server.js" ]
diff --git a/challenges-sample/the-varsity/challenge/package.json b/challenges-sample/the-varsity/challenge/package.json
new file mode 100644
index 00000000..a72939ea
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "The Varsity",
+ "version": "1.0.0",
+ "description": "",
+ "main": "server.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "SteakEnthusiast",
+ "license": "ISC",
+ "type": "module",
+ "dependencies": {
+ "cookie-parser": "^1.4.6",
+ "ejs": "^3.1.9",
+ "express": "^4.18.2",
+ "jsonwebtoken": "^9.0.2"
+ },
+ "devDependencies": {
+ "nodemon": "^3.0.2"
+ }
+}
diff --git a/challenges-sample/the-varsity/challenge/server.js b/challenges-sample/the-varsity/challenge/server.js
new file mode 100644
index 00000000..c0a1a6d1
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/server.js
@@ -0,0 +1,139 @@
+import express from "express";
+import jwt from "jsonwebtoken";
+import cookieParser from "cookie-parser";
+import crypto from "crypto";
+const FLAG = process.env.FLAG || "uoftctf{this_is_a_fake_flag}";
+const app = express();
+app.use(express.json());
+app.use(cookieParser());
+app.use(express.static("static"));
+app.set("view engine", "ejs");
+
+const JWT_SECRET = crypto.randomBytes(64).toString("hex");
+
+const articles = [
+ {
+ "title": "Pioneering the Future: UofT's Revolutionary AI Research",
+ "content": "The University of Toronto continues to lead groundbreaking research in artificial intelligence, with its latest project aiming to develop algorithms that can understand emotions in text. Spearheaded by a team of international students, this initiative promises to revolutionize how machines interact with human language."
+ },
+ {
+ "title": "Engineering Triumph: UofT Students Build Record-Breaking Solar Car",
+ "content": "A team of engineering students from the University of Toronto has broken international records with their latest solar-powered vehicle design. The car, named 'Solaris', is a testament to sustainable engineering and has won multiple awards in global competitions."
+ },
+ {
+ "title": "UofT's Theatre Group Takes Centre Stage with Revolutionary Performance",
+ "content": "The University of Toronto's theatre society has taken the art world by storm with its latest production, an innovative interpretation of Shakespeare's Hamlet. With a diverse cast and a unique, modern twist, the performance has garnered critical acclaim and a sold-out season."
+ },
+ {
+ "title": "Medical Breakthrough: UofT Students Contribute to Cancer Research",
+ "content": "In a significant stride towards fighting cancer, a group of biomedical students from the University of Toronto has contributed to major research findings. Their work focuses on a novel treatment approach that promises to reduce side effects and improve patient outcomes."
+ },
+ {
+ "title": "Green Revolution: UofT's Commitment to Sustainability",
+ "content": "The University of Toronto has launched a new initiative to make its campuses more sustainable. From reducing waste to promoting green technology, the university is dedicated to creating a better environment for students and the surrounding community."
+ },
+ {
+ "title": "Cultural Mosaic: UofT's International Festival Highlights Global Unity",
+ "content": "Celebrating diversity and unity, the University of Toronto's annual International Festival has once again brought together students from over 150 countries. The event featured cultural performances, food stalls, and interactive workshops, highlighting the rich cultural tapestry of the university's community."
+ },
+ {
+ "title": "Tech Titans: UofT's Startup Accelerator Nurtures Next Generation Innovators",
+ "content": "The University of Toronto's startup accelerator has become a hub for budding entrepreneurs. Offering mentorship, funding, and resources, the program has helped launch some of the most innovative tech companies in the country."
+ },
+ {
+ "title": "Historic Discovery: UofT Archaeologists Unearth Ancient Artifacts",
+ "content": "A team of archaeologists from the University of Toronto has made a historic discovery, unearthing ancient artifacts believed to be over 5,000 years old. This finding provides new insights into early human civilizations and has attracted international attention."
+ },
+ {
+ "title": "Fitness First: UofT's New Wellness Program Promotes Student Health",
+ "content": "With a focus on student well-being, the University of Toronto has introduced a comprehensive wellness program. Offering fitness classes, mental health resources, and nutritional guidance, the initiative aims to support the holistic health of all students."
+ },
+ {
+ title: "UofT Hosts its 2nd Inaugural Capture the Flag Event",
+ content: "Your flag is: " + FLAG,
+ },
+];
+
+app.get("/", (req, res) => {
+ const token = req.cookies.token;
+
+ if (token) {
+ try {
+ const decoded = jwt.verify(token, JWT_SECRET);
+ res.render("user", {
+ username: decoded.username,
+ subscription: decoded.subscription,
+ articles: articles,
+ });
+ } catch (error) {
+ res.clearCookie("token");
+ res.redirect("/register");
+ }
+ } else {
+ res.redirect("/register");
+ }
+});
+
+app.get("/register", (req, res) => {
+ res.render("register");
+});
+
+app.post("/register", (req, res) => {
+ const { username, voucher } = req.body;
+
+ if (
+ typeof username === "string" &&
+ (!voucher || typeof voucher === "string")
+ ) {
+ const subscription = voucher === FLAG + JWT_SECRET ? "premium" : "guest";
+ if (voucher && subscription === "guest") {
+ return res.status(400).json({ message: "Invalid voucher" });
+ }
+ const userToken = jwt.sign({ username, subscription }, JWT_SECRET, {
+ expiresIn: "1d",
+ });
+ res.cookie("token", userToken, { httpOnly: true });
+ return res.json({ message: "Registration successful", subscription });
+ }
+
+ return res.status(400).json({ message: "Invalid username or voucher" });
+});
+
+app.post("/article", (req, res) => {
+ const token = req.cookies.token;
+
+ if (token) {
+ try {
+ const decoded = jwt.verify(token, JWT_SECRET);
+
+ let issue = req.body.issue;
+
+ if (req.body.issue < 0) {
+ return res.status(400).json({ message: "Invalid issue number" });
+ }
+
+ if (decoded.subscription !== "premium" && issue >= 9) {
+ return res
+ .status(403)
+ .json({ message: "Please subscribe to access this issue" });
+ }
+
+ issue = parseInt(issue);
+
+ if (Number.isNaN(issue) || issue > articles.length - 1) {
+ return res.status(400).json({ message: "Invalid issue number" });
+ }
+
+ return res.json(articles[issue]);
+ } catch (error) {
+ res.clearCookie("token");
+ return res.status(403).json({ message: "Not Authenticated" });
+ }
+ } else {
+ return res.status(403).json({ message: "Not Authenticated" });
+ }
+});
+
+app.listen(3000, () => {
+ console.log("Server running on port 3000");
+});
diff --git a/challenges-sample/the-varsity/challenge/static/css/index.css b/challenges-sample/the-varsity/challenge/static/css/index.css
new file mode 100644
index 00000000..60ec89d1
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/static/css/index.css
@@ -0,0 +1,55 @@
+body, html {
+ font-family: Arial, sans-serif;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ background-color: #f7f7f7;
+}
+
+.container {
+ width: 80%;
+ text-align: center;
+ background-color: #fff;
+ padding: 20px;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+ margin-top: 50px;
+}
+
+h1 {
+ color: #333;
+}
+
+#statusMessage {
+ margin: 20px 0;
+ color: #555;
+}
+
+#articleSelector {
+ margin: 20px 0;
+}
+
+select {
+ padding: 10px;
+ margin-right: 10px;
+}
+
+button {
+ padding: 10px 20px;
+ background-color: #0056b3;
+ color: white;
+ border: none;
+ cursor: pointer;
+}
+
+button:hover {
+ background-color: #004494;
+}
+
+#articles {
+ border: 1px solid #ddd;
+ padding: 20px;
+ margin-top: 20px;
+}
diff --git a/challenges-sample/the-varsity/challenge/static/css/register.css b/challenges-sample/the-varsity/challenge/static/css/register.css
new file mode 100644
index 00000000..50bfa341
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/static/css/register.css
@@ -0,0 +1,65 @@
+body, html {
+ font-family: Arial, sans-serif;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ background-color: #f7f7f7;
+}
+
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ width: 350px;
+ border: 1px solid #ddd;
+ padding: 20px;
+ background-color: #fff;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+}
+
+h1 {
+ text-align: center;
+ margin-bottom: 20px;
+}
+
+.form-group {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ width: 100%;
+ margin-bottom: 15px;
+}
+
+label, input[type=checkbox] {
+ display: block;
+ margin-bottom: 5px;
+}
+
+input[type=text], select, button {
+ width: calc(100% - 20px);
+ padding: 10px;
+ border: 1px solid #ddd;
+ margin-top: 5px;
+}
+
+.checkbox-group {
+ display: flex;
+ align-items: center;
+}
+
+button {
+ width: 100%;
+ padding: 10px;
+ background-color: #0056b3;
+ color: white;
+ border: none;
+ cursor: pointer;
+}
+
+button:hover {
+ background-color: #004494;
+}
diff --git a/challenges-sample/the-varsity/challenge/static/js/index.js b/challenges-sample/the-varsity/challenge/static/js/index.js
new file mode 100644
index 00000000..33d690e4
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/static/js/index.js
@@ -0,0 +1,36 @@
+function requestArticle() {
+ const articleNum = document.getElementById("articleNum").value;
+ const statusMessage = document.getElementById("statusMessage");
+ const articlesDiv = document.getElementById("articles");
+
+ fetch("/article", {
+ method: "POST",
+ credentials: "same-origin",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ issue: articleNum }),
+ })
+ .then((response) => {
+ if (!response.ok) {
+ return response.json().then((err) => {
+ throw err;
+ });
+ }
+ return response.json();
+ })
+ .then((article) => {
+ if (articlesDiv && statusMessage) {
+ articlesDiv.innerHTML = `
${article.title}
${article.content}
`;
+ statusMessage.textContent = "Enjoy reading!";
+ }
+ })
+ .catch((error) => {
+ if (statusMessage) {
+ statusMessage.textContent = "Couldn't load article!";
+
+ articlesDiv.innerHTML = error.message || "Unknown error";
+ }
+ console.error("Error:", error);
+ });
+}
diff --git a/challenges-sample/the-varsity/challenge/static/js/register.js b/challenges-sample/the-varsity/challenge/static/js/register.js
new file mode 100644
index 00000000..9d9bd5c0
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/static/js/register.js
@@ -0,0 +1,34 @@
+function toggleVoucher() {
+ const voucherGroup = document.getElementById("voucherGroup");
+ voucherGroup.style.display = document.getElementById("hasVoucher").checked
+ ? "block"
+ : "none";
+}
+
+document.getElementById("registrationForm").onsubmit = function (event) {
+ event.preventDefault();
+ const username = document.getElementById("username").value;
+ const voucher = document.getElementById("hasVoucher").checked
+ ? document.getElementById("voucher").value
+ : "";
+
+ fetch("/register", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ username, voucher }),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ if (data.message === "Invalid voucher") {
+ document.getElementById("feedback").textContent = data.message;
+ } else {
+ document.cookie = `token=${data.token};path=/`;
+ window.location.href = "/";
+ }
+ })
+ .catch((error) => {
+ console.error("Error:", error);
+ });
+};
diff --git a/challenges-sample/the-varsity/challenge/views/register.ejs b/challenges-sample/the-varsity/challenge/views/register.ejs
new file mode 100644
index 00000000..e5d60493
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/views/register.ejs
@@ -0,0 +1,31 @@
+
+
+
+
+
+ Register for Access
+
+
+
+
+
Register for The Varsity
+
+
+
+
+
diff --git a/challenges-sample/the-varsity/challenge/views/user.ejs b/challenges-sample/the-varsity/challenge/views/user.ejs
new file mode 100644
index 00000000..f78c730f
--- /dev/null
+++ b/challenges-sample/the-varsity/challenge/views/user.ejs
@@ -0,0 +1,33 @@
+
+
+
+
+
+ Welcome <%= username %>!
+
+
+
+
+
Greetings, <%= username %>!
+ <% if (subscription === 'premium') { %>
+
As a premium member, you have exclusive access to all articles, including the latest insights and analyses. Enjoy your full access!
+ <% } else { %>
+
You are currently exploring as a guest. Upgrade to premium to unlock our full library, including our most recent and in-depth articles.
+ <% } %>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/challenges-sample/the-varsity/flag-handler/flag-getter.txt b/challenges-sample/the-varsity/flag-handler/flag-getter.txt
new file mode 100644
index 00000000..d8fedfb4
--- /dev/null
+++ b/challenges-sample/the-varsity/flag-handler/flag-getter.txt
@@ -0,0 +1 @@
+flag getter
\ No newline at end of file
diff --git a/challenges-sample/the-varsity/flag-handler/flag-setter.txt b/challenges-sample/the-varsity/flag-handler/flag-setter.txt
new file mode 100644
index 00000000..df42dade
--- /dev/null
+++ b/challenges-sample/the-varsity/flag-handler/flag-setter.txt
@@ -0,0 +1 @@
+flag setter
\ No newline at end of file
diff --git a/challenges-sample/the-varsity/katana.toml b/challenges-sample/the-varsity/katana.toml
new file mode 100644
index 00000000..f34742d0
--- /dev/null
+++ b/challenges-sample/the-varsity/katana.toml
@@ -0,0 +1,13 @@
+[challenge.author]
+name = "paradox"
+email = "paradox@katana.local"
+
+[challenge.metadata]
+name = "knock"
+flag = "dice{1_d00r_y0u_d00r_w3_a11_d00r_f0r_1_d00r}"
+description = "Knock knock? Who's there? Another pastebin!!"
+type = "web"
+points = 100
+
+[challenge.env]
+port_mappings = ["3000:3000"]
\ No newline at end of file
diff --git a/challenges-sample/vmcalc/challenge-checker/Dockerfile b/challenges-sample/vmcalc/challenge-checker/Dockerfile
new file mode 100644
index 00000000..0474613d
--- /dev/null
+++ b/challenges-sample/vmcalc/challenge-checker/Dockerfile
@@ -0,0 +1,17 @@
+# Use an official base image
+FROM ubuntu:latest
+
+# Set the working directory in the container
+WORKDIR /app
+
+# Copy the current directory contents into the container at /app
+COPY scheduler.txt /app
+
+# Make port 80 available to the world outside this container
+EXPOSE 80
+
+# # Define environment variable
+# ENV NAME World
+
+# Run command when the container launches
+CMD ["echo", "container created successfully"]
diff --git a/challenges-sample/vmcalc/challenge-checker/challenge-checker.txt b/challenges-sample/vmcalc/challenge-checker/challenge-checker.txt
new file mode 100644
index 00000000..cc4198f5
--- /dev/null
+++ b/challenges-sample/vmcalc/challenge-checker/challenge-checker.txt
@@ -0,0 +1 @@
+challenge checker
\ No newline at end of file
diff --git a/challenges-sample/vmcalc/challenge-checker/requirements.txt b/challenges-sample/vmcalc/challenge-checker/requirements.txt
new file mode 100644
index 00000000..c69335c0
--- /dev/null
+++ b/challenges-sample/vmcalc/challenge-checker/requirements.txt
@@ -0,0 +1 @@
+requirements of challenge-checker
\ No newline at end of file
diff --git a/challenges-sample/vmcalc/challenge-checker/scheduler.txt b/challenges-sample/vmcalc/challenge-checker/scheduler.txt
new file mode 100644
index 00000000..fb158aef
--- /dev/null
+++ b/challenges-sample/vmcalc/challenge-checker/scheduler.txt
@@ -0,0 +1 @@
+contains informations about schedules
\ No newline at end of file
diff --git a/challenges_sample/vmcalc/vmcalc/.dockerignore b/challenges-sample/vmcalc/challenge/.dockerignore
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/.dockerignore
rename to challenges-sample/vmcalc/challenge/.dockerignore
diff --git a/challenges_sample/vmcalc/vmcalc/Dockerfile b/challenges-sample/vmcalc/challenge/Dockerfile
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/Dockerfile
rename to challenges-sample/vmcalc/challenge/Dockerfile
diff --git a/challenges_sample/vmcalc/vmcalc/challenge.yaml b/challenges-sample/vmcalc/challenge/challenge.yaml
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/challenge.yaml
rename to challenges-sample/vmcalc/challenge/challenge.yaml
diff --git a/challenges_sample/vmcalc/vmcalc/dist.tar b/challenges-sample/vmcalc/challenge/dist.tar
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/dist.tar
rename to challenges-sample/vmcalc/challenge/dist.tar
diff --git a/challenges_sample/vmcalc/vmcalc/flag.txt b/challenges-sample/vmcalc/challenge/flag.txt
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/flag.txt
rename to challenges-sample/vmcalc/challenge/flag.txt
diff --git a/challenges_sample/vmcalc/vmcalc/index.js b/challenges-sample/vmcalc/challenge/index.js
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/index.js
rename to challenges-sample/vmcalc/challenge/index.js
diff --git a/challenges_sample/vmcalc/vmcalc/package.json b/challenges-sample/vmcalc/challenge/package.json
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/package.json
rename to challenges-sample/vmcalc/challenge/package.json
diff --git a/challenges_sample/vmcalc/vmcalc/views/admin.hbs b/challenges-sample/vmcalc/challenge/views/admin.hbs
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/views/admin.hbs
rename to challenges-sample/vmcalc/challenge/views/admin.hbs
diff --git a/challenges_sample/vmcalc/vmcalc/views/index.hbs b/challenges-sample/vmcalc/challenge/views/index.hbs
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc/views/index.hbs
rename to challenges-sample/vmcalc/challenge/views/index.hbs
diff --git a/challenges-sample/vmcalc/flag-handler/flag-getter.txt b/challenges-sample/vmcalc/flag-handler/flag-getter.txt
new file mode 100644
index 00000000..d8fedfb4
--- /dev/null
+++ b/challenges-sample/vmcalc/flag-handler/flag-getter.txt
@@ -0,0 +1 @@
+flag getter
\ No newline at end of file
diff --git a/challenges-sample/vmcalc/flag-handler/flag-setter.txt b/challenges-sample/vmcalc/flag-handler/flag-setter.txt
new file mode 100644
index 00000000..df42dade
--- /dev/null
+++ b/challenges-sample/vmcalc/flag-handler/flag-setter.txt
@@ -0,0 +1 @@
+flag setter
\ No newline at end of file
diff --git a/challenges-sample/vmcalc/katana.toml b/challenges-sample/vmcalc/katana.toml
new file mode 100644
index 00000000..c954428a
--- /dev/null
+++ b/challenges-sample/vmcalc/katana.toml
@@ -0,0 +1,13 @@
+[challenge.author]
+name = "paradox"
+email = "paradox@katana.local"
+
+[challenge.metadata]
+name = "vmcalc"
+flag = "dice{y0u_4re_a_tru3_vm2_j4ilbreak3r!!!}"
+description = "A simple and very secure online calculator!"
+type = "web"
+points = 100
+
+[challenge.env]
+port_mappings = ["3000:3000"]
\ No newline at end of file
diff --git a/challenges_sample/vmcalc/vmcalc.tar.gz b/challenges-sample/vmcalc/vmcalc.tar.gz
similarity index 100%
rename from challenges_sample/vmcalc/vmcalc.tar.gz
rename to challenges-sample/vmcalc/vmcalc.tar.gz
diff --git a/challenges_sample/knock/knock.tar.gz b/challenges_sample/knock/knock.tar.gz
deleted file mode 100644
index 2895b7f4..00000000
Binary files a/challenges_sample/knock/knock.tar.gz and /dev/null differ
diff --git a/challenges_sample/knock/knock/Dockerfile b/challenges_sample/knock/knock/Dockerfile
deleted file mode 100644
index f14059ae..00000000
--- a/challenges_sample/knock/knock/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM node:17.4.0-buster-slim
-
-RUN mkdir -p /app
-
-WORKDIR /app
-
-COPY package.json .
-
-RUN yarn
-
-COPY . .
-
-USER node
-
-CMD ["node", "index.js"]
diff --git a/challenges_sample/knock/knock/challenge.yaml b/challenges_sample/knock/knock/challenge.yaml
deleted file mode 100644
index 60edf523..00000000
--- a/challenges_sample/knock/knock/challenge.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: knock-knock
-author: BrownieInMotion
-description: |-
- Knock knock? Who's there? Another pastebin!!
-
- ${link_main_0}
-
-flag: dice{1_d00r_y0u_d00r_w3_a11_d00r_f0r_1_d00r}
-
-provide:
- - ./index.js
- - ./Dockerfile
-
-containers:
- main:
- build: .
- ports:
- - 3000
- environment:
- FLAG: "dice{1_d00r_y0u_d00r_w3_a11_d00r_f0r_1_d00r}"
-
-expose:
- main:
- - target: 3000
- http: knock-knock
- healthContent: Create Paste
diff --git a/challenges_sample/knock/knock/index.js b/challenges_sample/knock/knock/index.js
deleted file mode 100644
index 82844e68..00000000
--- a/challenges_sample/knock/knock/index.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const crypto = require('crypto');
-
-class Database {
- constructor() {
- this.notes = [];
- this.secret = `secret-${crypto.randomUUID}`;
- }
-
- createNote({ data }) {
- const id = this.notes.length;
- this.notes.push(data);
- return {
- id,
- token: this.generateToken(id),
- };
- }
-
- getNote({ id, token }) {
- if (token !== this.generateToken(id)) return { error: 'invalid token' };
- if (id >= this.notes.length) return { error: 'note not found' };
- return { data: this.notes[id] };
- }
-
- generateToken(id) {
- return crypto
- .createHmac('sha256', this.secret)
- .update(id.toString())
- .digest('hex');
- }
-}
-
-const db = new Database();
-db.createNote({ data: process.env.FLAG });
-
-const express = require('express');
-const app = express();
-
-app.use(express.urlencoded({ extended: false }));
-app.use(express.static('public'));
-
-app.post('/create', (req, res) => {
- const data = req.body.data ?? 'no data provided.';
- const { id, token } = db.createNote({ data: data.toString() });
- res.redirect(`/note?id=${id}&token=${token}`);
-});
-
-app.get('/note', (req, res) => {
- const { id, token } = req.query;
- const note = db.getNote({
- id: parseInt(id ?? '-1'),
- token: (token ?? '').toString(),
- });
- if (note.error) {
- res.send(note.error);
- } else {
- res.send(note.data);
- }
-});
-
-app.listen(3000, () => {
- console.log('listening on port 3000');
-});
diff --git a/challenges_sample/knock/knock/package.json b/challenges_sample/knock/knock/package.json
deleted file mode 100644
index d4227a06..00000000
--- a/challenges_sample/knock/knock/package.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "knock-knock",
- "version": "1.0.0",
- "main": "index.js",
- "license": "MIT",
- "dependencies": {
- "express": "^4.17.2"
- }
-}
diff --git a/challenges_sample/knock/knock/public/index.html b/challenges_sample/knock/knock/public/index.html
deleted file mode 100644
index 526b2dc5..00000000
--- a/challenges_sample/knock/knock/public/index.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
Create Paste
-
-
diff --git a/challenges_sample/knock/knock/yarn.lock b/challenges_sample/knock/knock/yarn.lock
deleted file mode 100644
index 1dd58a8c..00000000
--- a/challenges_sample/knock/knock/yarn.lock
+++ /dev/null
@@ -1,352 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-accepts@~1.3.7:
- version "1.3.8"
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
- integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
- dependencies:
- mime-types "~2.1.34"
- negotiator "0.6.3"
-
-array-flatten@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
- integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
-
-body-parser@1.19.1:
- version "1.19.1"
- resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4"
- integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==
- dependencies:
- bytes "3.1.1"
- content-type "~1.0.4"
- debug "2.6.9"
- depd "~1.1.2"
- http-errors "1.8.1"
- iconv-lite "0.4.24"
- on-finished "~2.3.0"
- qs "6.9.6"
- raw-body "2.4.2"
- type-is "~1.6.18"
-
-bytes@3.1.1:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a"
- integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==
-
-content-disposition@0.5.4:
- version "0.5.4"
- resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
- integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
- dependencies:
- safe-buffer "5.2.1"
-
-content-type@~1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
- integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
-
-cookie-signature@1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
- integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
-
-cookie@0.4.1:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
- integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
-
-debug@2.6.9:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-depd@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
- integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
-
-destroy@~1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
- integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
-
-ee-first@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
- integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
-
-encodeurl@~1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
- integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-
-escape-html@~1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
- integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
-
-etag@~1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
- integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
-
-express@^4.17.2:
- version "4.17.2"
- resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3"
- integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==
- dependencies:
- accepts "~1.3.7"
- array-flatten "1.1.1"
- body-parser "1.19.1"
- content-disposition "0.5.4"
- content-type "~1.0.4"
- cookie "0.4.1"
- cookie-signature "1.0.6"
- debug "2.6.9"
- depd "~1.1.2"
- encodeurl "~1.0.2"
- escape-html "~1.0.3"
- etag "~1.8.1"
- finalhandler "~1.1.2"
- fresh "0.5.2"
- merge-descriptors "1.0.1"
- methods "~1.1.2"
- on-finished "~2.3.0"
- parseurl "~1.3.3"
- path-to-regexp "0.1.7"
- proxy-addr "~2.0.7"
- qs "6.9.6"
- range-parser "~1.2.1"
- safe-buffer "5.2.1"
- send "0.17.2"
- serve-static "1.14.2"
- setprototypeof "1.2.0"
- statuses "~1.5.0"
- type-is "~1.6.18"
- utils-merge "1.0.1"
- vary "~1.1.2"
-
-finalhandler@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
- integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
- dependencies:
- debug "2.6.9"
- encodeurl "~1.0.2"
- escape-html "~1.0.3"
- on-finished "~2.3.0"
- parseurl "~1.3.3"
- statuses "~1.5.0"
- unpipe "~1.0.0"
-
-forwarded@0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
- integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
-
-fresh@0.5.2:
- version "0.5.2"
- resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
- integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
-
-http-errors@1.8.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
- integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
- dependencies:
- depd "~1.1.2"
- inherits "2.0.4"
- setprototypeof "1.2.0"
- statuses ">= 1.5.0 < 2"
- toidentifier "1.0.1"
-
-iconv-lite@0.4.24:
- version "0.4.24"
- resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
- integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
- dependencies:
- safer-buffer ">= 2.1.2 < 3"
-
-inherits@2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
- integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-ipaddr.js@1.9.1:
- version "1.9.1"
- resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
- integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
-
-media-typer@0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
- integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
-
-merge-descriptors@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
- integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
-
-methods@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
- integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
-
-mime-db@1.51.0:
- version "1.51.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
- integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
-
-mime-types@~2.1.24, mime-types@~2.1.34:
- version "2.1.34"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
- integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
- dependencies:
- mime-db "1.51.0"
-
-mime@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
- integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
-
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-
-ms@2.1.3:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
- integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-
-negotiator@0.6.3:
- version "0.6.3"
- resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
- integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
-
-on-finished@~2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
- integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
- dependencies:
- ee-first "1.1.1"
-
-parseurl@~1.3.3:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
- integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
-
-path-to-regexp@0.1.7:
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
- integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
-
-proxy-addr@~2.0.7:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
- integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
- dependencies:
- forwarded "0.2.0"
- ipaddr.js "1.9.1"
-
-qs@6.9.6:
- version "6.9.6"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee"
- integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==
-
-range-parser@~1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
- integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
-
-raw-body@2.4.2:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32"
- integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==
- dependencies:
- bytes "3.1.1"
- http-errors "1.8.1"
- iconv-lite "0.4.24"
- unpipe "1.0.0"
-
-safe-buffer@5.2.1:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
- integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
-"safer-buffer@>= 2.1.2 < 3":
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
- integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-
-send@0.17.2:
- version "0.17.2"
- resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820"
- integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==
- dependencies:
- debug "2.6.9"
- depd "~1.1.2"
- destroy "~1.0.4"
- encodeurl "~1.0.2"
- escape-html "~1.0.3"
- etag "~1.8.1"
- fresh "0.5.2"
- http-errors "1.8.1"
- mime "1.6.0"
- ms "2.1.3"
- on-finished "~2.3.0"
- range-parser "~1.2.1"
- statuses "~1.5.0"
-
-serve-static@1.14.2:
- version "1.14.2"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa"
- integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==
- dependencies:
- encodeurl "~1.0.2"
- escape-html "~1.0.3"
- parseurl "~1.3.3"
- send "0.17.2"
-
-setprototypeof@1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
- integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
-
-"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
- integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
-
-toidentifier@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
- integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
-
-type-is@~1.6.18:
- version "1.6.18"
- resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
- integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
- dependencies:
- media-typer "0.3.0"
- mime-types "~2.1.24"
-
-unpipe@1.0.0, unpipe@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
- integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
-
-utils-merge@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
- integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
-
-vary@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
- integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
diff --git a/go.mod b/go.mod
index 2d3a977a..13ded235 100644
--- a/go.mod
+++ b/go.mod
@@ -20,6 +20,7 @@ require (
k8s.io/api v0.28.1
k8s.io/apimachinery v0.28.1
k8s.io/client-go v0.28.1
+ k8s.io/kubectl v0.28.1
)
require (
@@ -125,7 +126,6 @@ require (
k8s.io/component-base v0.28.1 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230811205723-7ac0aad8c58d // indirect
- k8s.io/kubectl v0.28.1 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
diff --git a/go.sum b/go.sum
index b6096ca6..96b5b9ca 100644
--- a/go.sum
+++ b/go.sum
@@ -32,6 +32,7 @@ github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEM
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -224,8 +225,7 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
-github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
@@ -241,6 +241,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -430,18 +431,12 @@ gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.28.0-alpha.3 h1:dl9ku8PmbvD7VFdgYzA34SRGsg5hpmDeqZUC670kVjw=
-k8s.io/api v0.28.0-alpha.3/go.mod h1:8xUcnnu+0XlJiU0p9mwS7tRpUB1ce+XZrCYsEHeUQRw=
k8s.io/api v0.28.1 h1:i+0O8k2NPBCPYaMB+uCkseEbawEt/eFaiRqUx8aB108=
k8s.io/api v0.28.1/go.mod h1:uBYwID+66wiL28Kn2tBjBYQdEU0Xk0z5qF8bIBqk/Dg=
-k8s.io/apimachinery v0.28.0-alpha.3 h1:poqReta738jpeYUyvxXxYbOk6hj5vc1EcKxyo0zhklk=
-k8s.io/apimachinery v0.28.0-alpha.3/go.mod h1:tAiIbF8KB8+Ri2DfUWwZGwNOThIwM0fhXLnOymriu+4=
k8s.io/apimachinery v0.28.1 h1:EJD40og3GizBSV3mkIoXQBsws32okPOy+MkRyzh6nPY=
k8s.io/apimachinery v0.28.1/go.mod h1:X0xh/chESs2hP9koe+SdIAcXWcQ+RM5hy0ZynB+yEvw=
k8s.io/cli-runtime v0.28.1 h1:7Njc4eD5kaO4tYdSYVJJEs54koYD/vT6gxOq8dEVf9g=
k8s.io/cli-runtime v0.28.1/go.mod h1:yIThSWkAVLqeRs74CMkq6lNFW42GyJmvMtcNn01SZho=
-k8s.io/client-go v0.28.0-alpha.3 h1:CPcmGXW3lRogryie7htr93ZIitk6H+zrzPns3TpuFyY=
-k8s.io/client-go v0.28.0-alpha.3/go.mod h1:1KTCIXQZjy18QNeXI6zDkq1w2E4UP6gjl1fp5QRF3mo=
k8s.io/client-go v0.28.1 h1:pRhMzB8HyLfVwpngWKE8hDcXRqifh1ga2Z/PU9SXVK8=
k8s.io/client-go v0.28.1/go.mod h1:pEZA3FqOsVkCc07pFVzK076R+P/eXqsgx5zuuRWukNE=
k8s.io/component-base v0.28.1 h1:LA4AujMlK2mr0tZbQDZkjWbdhTV5bRyEyAFe0TJxlWg=
diff --git a/katana-services b/katana-services
deleted file mode 160000
index a79e56b2..00000000
--- a/katana-services
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit a79e56b2458f84a42fa51d293fa1bce036af57b5
diff --git a/kubernetes/manifests/_setup.yml b/kubernetes/manifests/_setup.yml
index 011f4cd2..90b4bc43 100644
--- a/kubernetes/manifests/_setup.yml
+++ b/kubernetes/manifests/_setup.yml
@@ -35,7 +35,7 @@ metadata:
name: cluster-admin-role
namespace: katana
rules:
- - apiGroups: ["apps"]
+ - apiGroups: ["apps",""]
resources:
["pods", "pods/exec", "services", "statefulsets", "statefulsets/scale"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
diff --git a/kubernetes/manifests/kashira.yml b/kubernetes/manifests/kashira.yml
index 2a6d3841..b189f912 100644
--- a/kubernetes/manifests/kashira.yml
+++ b/kubernetes/manifests/kashira.yml
@@ -28,7 +28,8 @@ spec:
serviceAccountName: cluster-admin
containers:
- name: kashira
- image: harbor.katana.local/katana/kashira
+ image: iiteens/kashira
+ imagePullPolicy: Always # added for ease may be remove later
ports:
- containerPort: 80
volumeMounts:
diff --git a/kubernetes/manifests/kissaki.yml b/kubernetes/manifests/kissaki.yml
index 34e74787..f4af92bd 100644
--- a/kubernetes/manifests/kissaki.yml
+++ b/kubernetes/manifests/kissaki.yml
@@ -29,6 +29,7 @@ spec:
containers:
- name: kissaki
image: harbor.katana.local/katana/kissaki
+ imagePullPolicy: Always # added for ease may be remove later
ports:
- containerPort: 80
volumeMounts:
@@ -60,4 +61,4 @@ spec:
ports:
- protocol: TCP
port: 80
- targetPort: 80
+ targetPort: 5000 #Kissaki port in katana-services is in 5000, add this to docs to main consistency
diff --git a/kubernetes/manifests/logs.yml b/kubernetes/manifests/logs.yml
deleted file mode 100644
index 7f174c09..00000000
--- a/kubernetes/manifests/logs.yml
+++ /dev/null
@@ -1,234 +0,0 @@
----
-apiVersion: apps/v1
-kind: StatefulSet
-metadata:
- name: es-cluster
- namespace: katana
-spec:
- serviceName: elasticsearch
- replicas: 3
- selector:
- matchLabels:
- app: elasticsearch
- template:
- metadata:
- labels:
- app: elasticsearch
- spec:
- containers:
- - name: elasticsearch
- image: docker.elastic.co/elasticsearch/elasticsearch:7.5.0
- resources:
- limits:
- cpu: 1000m
- requests:
- cpu: 100m
- ports:
- - containerPort: 9200
- name: rest
- protocol: TCP
- - containerPort: 9300
- name: inter-node
- protocol: TCP
- volumeMounts:
- - name: data
- mountPath: /usr/share/elasticsearch/data
- env:
- - name: cluster.name
- value: k8s-logs
- - name: node.name
- valueFrom:
- fieldRef:
- fieldPath: metadata.name
- - name: discovery.seed_hosts
- value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
- - name: cluster.initial_master_nodes
- value: "es-cluster-0,es-cluster-1,es-cluster-2"
- - name: ES_JAVA_OPTS
- value: "-Xms512m -Xmx512m"
- initContainers:
- - name: fix-permissions
- image: busybox
- command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
- securityContext:
- privileged: true
- volumeMounts:
- - name: data
- mountPath: /usr/share/elasticsearch/data
- - name: increase-vm-max-map
- image: busybox
- command: ["sysctl", "-w", "vm.max_map_count=262144"]
- securityContext:
- privileged: true
- - name: increase-fd-ulimit
- image: busybox
- command: ["sh", "-c", "ulimit -n 65536"]
- securityContext:
- privileged: true
- volumeClaimTemplates:
- - metadata:
- name: data
- labels:
- app: elasticsearch
- spec:
- accessModes: [ "ReadWriteOnce" ]
- resources:
- requests:
- storage: 3Gi
-
----
-apiVersion: v1
-kind: Service
-metadata:
- name: elasticsearch
- namespace: katana
- labels:
- app: elasticsearch
-spec:
- selector:
- app: elasticsearch
- clusterIP: None
- ports:
- - port: 9200
- name: rest
- - port: 9300
- name: inter-node
-
----
-apiVersion: apps/v1
-kind: DaemonSet
-metadata:
- name: fluentd
- namespace: katana
- labels:
- app: fluentd
-spec:
- selector:
- matchLabels:
- app: fluentd
- template:
- metadata:
- labels:
- app: fluentd
- spec:
- serviceAccount: fluentd
- serviceAccountName: fluentd
- containers:
- - name: fluentd
- image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
- env:
- - name: FLUENT_ELASTICSEARCH_HOST
- value: "elasticsearch.default.svc.cluster.local"
- - name: FLUENT_ELASTICSEARCH_PORT
- value: "9200"
- - name: FLUENT_ELASTICSEARCH_SCHEME
- value: "http"
- - name: FLUENTD_SYSTEMD_CONF
- value: disable
- resources:
- limits:
- memory: 512Mi
- requests:
- cpu: 100m
- memory: 200Mi
- volumeMounts:
- - name: varlog
- mountPath: /var/log
- - name: varlibdockercontainers
- mountPath: /var/lib/docker/containers
- readOnly: true
- terminationGracePeriodSeconds: 30
- volumes:
- - name: varlog
- hostPath:
- path: /var/log
- - name: varlibdockercontainers
- hostPath:
- path: /var/lib/docker/containers
-
----
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
- name: fluentd
-roleRef:
- kind: ClusterRole
- name: fluentd
- apiGroup: rbac.authorization.k8s.io
-subjects:
-- kind: ServiceAccount
- name: fluentd
- namespace: katana
-
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: fluentd
- labels:
- app: fluentd
-rules:
-- apiGroups:
- - ""
- resources:
- - pods
- - namespaces
- verbs:
- - get
- - list
- - watch
-
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: fluentd
- labels:
- app: fluentd
-
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: kibana
- namespace: katana
- labels:
- app: kibana
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: kibana
- template:
- metadata:
- labels:
- app: kibana
- spec:
- containers:
- - name: kibana
- image: docker.elastic.co/kibana/kibana:7.5.0
- resources:
- limits:
- cpu: 1000m
- requests:
- cpu: 100m
- env:
- - name: ELASTICSEARCH_URL
- value: http://elasticsearch:9200
- ports:
- - containerPort: 5601
-
----
-apiVersion: v1
-kind: Service
-metadata:
- name: kibana-np
- namespace: katana
-spec:
- selector:
- app: kibana
- type: NodePort
- ports:
- - port: 8080
- targetPort: 5601
- nodePort: 30000
\ No newline at end of file
diff --git a/kubernetes/templates/runtime/cc.yml b/kubernetes/templates/runtime/cc.yml
new file mode 100644
index 00000000..4a045300
--- /dev/null
+++ b/kubernetes/templates/runtime/cc.yml
@@ -0,0 +1,40 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: {{.Namespace}}
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{.AppName}}-deployment
+ namespace: {{.Namespace}}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: {{.AppName}}
+ template:
+ metadata:
+ labels:
+ app: {{.AppName}}
+ spec:
+ serviceAccountName: cluster-admin
+ containers:
+ - name: {{.AppName}}
+ image: "harbor.katana.local/katana/"{{.Image}}
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 8080
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{.AppName}}-svc
+ namespace: {{.Namespace}}
+spec:
+ selector:
+ app: {{.AppName}}
+ ports:
+ - protocol: TCP
+ port: 80
+ targetPort: 8080
diff --git a/lib/deployment/deployment.go b/lib/deployment/deployment.go
index 594752f0..2c249c08 100644
--- a/lib/deployment/deployment.go
+++ b/lib/deployment/deployment.go
@@ -142,6 +142,7 @@ func DeployChallengeToCluster(challengeName, teamName string, firstPatch bool, r
teamNamespace := teamName + "-ns"
kubeclient, _ := utils.GetKubeClient()
+ //to-do verify image exist in harbor, wait for sometime if not return error
deploymentsClient := kubeclient.AppsV1().Deployments(teamNamespace)
imageName := "harbor.katana.local/katana/" + challengeName + ":latest"
if firstPatch {
@@ -213,3 +214,62 @@ func DeployChallengeToCluster(challengeName, teamName string, firstPatch bool, r
log.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName()+" in namespace "+teamNamespace)
return nil
}
+
+
+func DeployChallengeCheckerToCluster(challengeCheckerName, namespace string, replicas int32) error {
+
+ kubeclient, _ := utils.GetKubeClient()
+
+ deploymentsClient := kubeclient.AppsV1().Deployments(namespace)
+ imageName := "harbor.katana.local/katana/" + challengeCheckerName
+
+ manifest := &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: namespace,
+ Name: challengeCheckerName+"-deployment",
+ },
+ Spec: appsv1.DeploymentSpec{
+ Replicas: &replicas,
+ Selector: &metav1.LabelSelector{
+ MatchLabels: map[string]string{
+ "app": challengeCheckerName,
+ },
+ },
+ Template: v1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ "app": challengeCheckerName,
+ },
+ },
+ Spec: v1.PodSpec{
+ ServiceAccountName: "cluster-admin",
+ Containers: []v1.Container{
+ {
+ Name: challengeCheckerName,
+ Image: imageName,
+ ImagePullPolicy: v1.PullPolicy("Always"),
+ Ports: []v1.ContainerPort{
+ {
+ Name: "checker-port",
+ ContainerPort: 8080,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+
+ log.Println("Creating deployment...")
+ result, err := deploymentsClient.Create(context.TODO(), manifest, metav1.CreateOptions{})
+
+ if err != nil {
+ log.Println("Unable to create deployment")
+ panic(err)
+ }
+
+ log.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName()+" in namespace "+namespace)
+ return nil
+}
+
diff --git a/lib/utils/crypto.go b/lib/utils/crypto.go
index b3a06323..8917497a 100644
--- a/lib/utils/crypto.go
+++ b/lib/utils/crypto.go
@@ -29,6 +29,12 @@ func GenerateCerts(domain string, basePath string) error {
if err := RunCommand(cmd); err != nil {
return err
}
+
+ // using -traditional flag to get PKCS#1 [different header], otherwise 500 Internal Error
+ cmd = "openssl rsa -in "+basePath+"/ca.key -out "+basePath+"/ca.key -traditional"
+ if err := RunCommand(cmd); err != nil {
+ return err
+ }
// using -traditional flag to get PKCS#1 [different header], otherwise 500 Internal Error
cmd = "openssl rsa -in "+basePath+"/ca.key -out "+basePath+"/ca.key -traditional"
diff --git a/lib/utils/docker.go b/lib/utils/docker.go
index 48c51e85..30e08098 100644
--- a/lib/utils/docker.go
+++ b/lib/utils/docker.go
@@ -112,6 +112,74 @@ func BuildDockerImage(_ChallengeName string, _DockerfilePath string) {
}
+//this func is modified to pass args to dockerfile, so that name of challenge could be identified
+func BuildDockerImageCc(_ChallengeName string, _DockerfilePath string) {
+ buf := new(bytes.Buffer)
+ if err := Tar(_DockerfilePath, buf); err != nil {
+ log.Fatal(err, ": error tarring directory")
+ return
+ }
+ cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
+ if err != nil {
+ log.Fatal(err)
+ return
+ }
+
+ log.Println("Building Docker image, Please wait......")
+
+ imageBuildResponse, err := cli.ImageBuild(
+ context.Background(),
+ buf,
+ types.ImageBuildOptions{
+ Dockerfile: "Dockerfile",
+ Remove: true,
+ Tags: []string{"harbor.katana.local/katana/" + _ChallengeName},
+ BuildArgs: map[string]*string{"chall_name":&_ChallengeName},
+ },
+ )
+ if err != nil {
+ log.Fatal(err, " :unable to create image")
+ return
+ }
+
+ _, err = io.Copy(os.Stdout, imageBuildResponse.Body)
+ if err != nil {
+ log.Fatal(err, " :unable to read image build response")
+ return
+ }
+
+ log.Println("Docker image built successfully")
+
+ dockerLogin(configs.KatanaConfig.Harbor.Username, configs.KatanaConfig.Harbor.Password)
+
+ log.Println("Pushing Docker image to Harbor, please wait...")
+
+ authConfig := registry.AuthConfig{
+ Username: configs.KatanaConfig.Harbor.Username,
+ Password: configs.KatanaConfig.Harbor.Password,
+ }
+ authJSON, err := json.Marshal(authConfig)
+ if err != nil {
+ log.Fatal(err, ": error encoding credentials")
+ return
+ }
+
+ encodedAuth := Base64Encode(string(authJSON))
+
+ pushOptions := types.ImagePushOptions{
+ RegistryAuth: encodedAuth,
+ }
+
+ _, err = cli.ImagePush(context.Background(), "harbor.katana.local/katana/"+_ChallengeName, pushOptions)
+ if err != nil {
+ log.Fatal(err, " :unable to push docker image")
+ return
+ }
+
+ log.Println("Image Pushed to Harbor successfully")
+
+}
+
func DockerImageExists(imageName string) bool {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
diff --git a/services/challengedeployerservice/controller.go b/services/challengedeployerservice/controller.go
index f46bff33..add27bce 100644
--- a/services/challengedeployerservice/controller.go
+++ b/services/challengedeployerservice/controller.go
@@ -16,6 +16,7 @@ import (
g "github.com/sdslabs/katana/configs"
"github.com/sdslabs/katana/lib/deployment"
"github.com/sdslabs/katana/lib/utils"
+ "github.com/sdslabs/katana/services/infrasetservice"
"github.com/sdslabs/katana/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -23,7 +24,151 @@ import (
func Deploy(c *fiber.Ctx) error {
patch := false
replicas := int32(1)
- challengeType := "web"
+ challengeType := "web" //hardcoded-------------------------------------
+ log.Println("Starting")
+
+ //Read folder challenge by os
+ dir, err := os.Open("./challenges")
+
+ //Loop over all subfolders in the challenge folder
+ if err != nil {
+ log.Println("Error in opening challenges folder")
+ return err
+ }
+ defer dir.Close()
+
+ //Read all challenges in the folder
+ fileInfos, err := dir.Readdir(-1)
+ if err != nil {
+ log.Println("Error in reading challenges folder")
+ return err
+ }
+
+ res := make([][]string, 0)
+
+ //Loop over all folders
+ for _, fileInfo := range fileInfos {
+ //Check if it is a directory
+ if fileInfo.IsDir() {
+ //Get the challenger name
+ folderName := fileInfo.Name()
+ log.Println("Folder name is : " + folderName)
+ //Update challenge path to be absolute path
+ challengePath, _ := os.Getwd()
+ challengePath = challengePath + "/challenges/" + folderName
+ log.Println("Challenge path is : " + challengePath)
+ log.Println(challengePath + "/challenge/Dockerfile")
+
+ ccName := folderName + "-cc"
+ ccNamespace := "katana"
+
+ //Check if the folder has a Dockerfile
+ if _, err := os.Stat(challengePath + "/challenge/Dockerfile"); err != nil {
+ log.Println("Dockerfile not found in the " + folderName + " challenge folder. Please follow proper format.")
+ } else if _, err := os.Stat(challengePath + "/challenge-checker/Dockerfile"); err != nil {
+ log.Println("Dockerfile not found in the " + folderName + " challenge-checker folder. Please follow proper format.")
+ } else {
+ //pass path of folder which contains dockerfile
+ //Update challenge path to get dockerfile
+ utils.BuildDockerImage(folderName, challengePath+"/challenge")
+
+ //Update challenge-checker path to get dockerfile
+ infrasetservice.Apply_cc_yml(c, ccName, ccNamespace)
+ utils.BuildDockerImage(ccName, challengePath+"/challenge-checker")
+ deployment.DeployChallengeCheckerToCluster(ccName, ccNamespace, replicas)
+ url, err := createServiceForChallengeChecker(ccName, ccNamespace, 8080)
+ if err != nil {
+ res = append(res, []string{ccName, err.Error()})
+ } else {
+ res = append(res, []string{ccName, url})
+ }
+
+ clusterConfig := g.ClusterConfig
+ numberOfTeams := clusterConfig.TeamCount
+ for i := 0; i < int(numberOfTeams); i++ {
+ log.Println("-----------Deploying challenge for team: " + strconv.Itoa(i) + " --------")
+ teamName := "katana-team-" + strconv.Itoa(i)
+ deployment.DeployChallengeToCluster(folderName, teamName, patch, replicas)
+ url, err := createServiceForChallenge(folderName, teamName, 3000, i)
+ if err != nil {
+ res = append(res, []string{teamName, err.Error()})
+ } else {
+ res = append(res, []string{teamName, url})
+ }
+ }
+ }
+ copyChallengeIntoTsuka(challengePath, folderName, challengeType)
+ copyFlagDataIntoKashira(challengePath, folderName)
+ }
+ }
+ return c.JSON(res)
+}
+
+func Cc(c *fiber.Ctx) error {
+ replicas := int32(1)
+ log.Println("Starting")
+
+ //Read folder challenge by os
+ dir, err := os.Open("./challenges")
+
+ //Loop over all subfolders in the challenge folder
+ if err != nil {
+ log.Println("Error in opening challenges folder")
+ return err
+ }
+ defer dir.Close()
+
+ //Read all challenges in the folder
+ fileInfos, err := dir.Readdir(-1)
+ if err != nil {
+ log.Println("Error in reading challenges folder")
+ return err
+ }
+
+ res := make([][]string, 0)
+
+ //Loop over all folders
+ for _, fileInfo := range fileInfos {
+ //Check if it is a directory
+ if fileInfo.IsDir() {
+ //Get the challenger name
+ folderName := fileInfo.Name()
+ log.Println("Folder name is : " + folderName)
+ //Update challenge path to be absolute path
+ challengePath, _ := os.Getwd()
+ challengePath = challengePath + "/challenges/" + folderName
+ log.Println("Challenge path is : " + challengePath)
+ log.Println(challengePath + "/challenge/Dockerfile")
+
+ // '-cc' at last of ccName is convention which is also followed in kissaki for handling status
+ ccName := folderName + "-cc"
+ ccNamespace := "katana"
+
+ //Check if the folder has a Dockerfile
+ if _, err := os.Stat(challengePath + "/challenge-checker/Dockerfile"); err != nil {
+ log.Println("Dockerfile not found in the " + folderName + " challenge-checker folder. Please follow proper format.")
+ } else {
+
+ //Update challenge-checker path to get dockerfile
+ infrasetservice.Apply_cc_yml(c, ccName, ccNamespace)
+ utils.BuildDockerImageCc(ccName, challengePath+"/challenge-checker")
+ deployment.DeployChallengeCheckerToCluster(ccName, ccNamespace, replicas)
+ url, err := createServiceForChallengeChecker(ccName, ccNamespace, 8080)
+ if err != nil {
+ res = append(res, []string{ccName, err.Error()})
+ } else {
+ res = append(res, []string{ccName, url})
+ }
+ }
+ }
+ }
+ return c.JSON(res)
+}
+
+func Team(c *fiber.Ctx) error {
+ patch := false
+ replicas := int32(1)
+ challengeType := "web" //hardcoded-------------------------------------
log.Println("Starting")
//Read folder challenge by os
@@ -56,14 +201,15 @@ func Deploy(c *fiber.Ctx) error {
challengePath, _ := os.Getwd()
challengePath = challengePath + "/challenges/" + folderName
log.Println("Challenge path is : " + challengePath)
- log.Println(challengePath + "/" + folderName + "/" + folderName)
+ log.Println(challengePath + "/challenge/Dockerfile")
//Check if the folder has a Dockerfile
- if _, err := os.Stat(challengePath + "/" + folderName + "/" + folderName); err != nil {
+ if _, err := os.Stat(challengePath + "/challenge/Dockerfile"); err != nil {
log.Println("Dockerfile not found in the " + folderName + " challenge folder. Please follow proper format.")
} else {
+ //pass path of folder which contains dockerfile
//Update challenge path to get dockerfile
- utils.BuildDockerImage(folderName, challengePath+"/"+folderName+"/"+folderName)
+ utils.BuildDockerImage(folderName, challengePath+"/challenge")
clusterConfig := g.ClusterConfig
numberOfTeams := clusterConfig.TeamCount
@@ -81,7 +227,6 @@ func Deploy(c *fiber.Ctx) error {
}
copyChallengeIntoTsuka(challengePath, folderName, challengeType)
copyFlagDataIntoKashira(challengePath, folderName)
- copyChallengeCheckerIntoKissaki(challengePath, folderName)
}
}
return c.JSON(res)
@@ -153,7 +298,7 @@ func DeployChallenge(c *fiber.Ctx) error {
}
copyChallengeIntoTsuka(challengePath, folderName, challengeType)
copyFlagDataIntoKashira(challengePath, folderName)
- copyChallengeCheckerIntoKissaki(challengePath, folderName)
+ copyChallengeCheckerIntoKissaki(challengePath, folderName) // Retained this function for potential future use. Will evaluate and remove if found unnecessary during testing.
return c.JSON(res)
}
diff --git a/services/challengedeployerservice/helper.go b/services/challengedeployerservice/helper.go
index f704bdb8..3dea7372 100644
--- a/services/challengedeployerservice/helper.go
+++ b/services/challengedeployerservice/helper.go
@@ -14,7 +14,7 @@ import (
)
func copyChallengeIntoTsuka(dirPath string, challengeName string, challengeType string) error {
- localFilePath := dirPath + "/" + challengeName
+ localFilePath := dirPath + "/challenge"
pathInPod := "/opt/katana/katana_" + challengeType + "_" + challengeName + ".tar.gz"
log.Println("Testing" + localFilePath + "....and..." + pathInPod)
filename := challengeName
@@ -77,6 +77,21 @@ func createServiceForChallenge(challengeName, teamName string, targetPort int32,
return serviceName, nil
}
+func createServiceForChallengeChecker(challengeCheckerName, namespace string, targetPort int32) (string, error) {
+ kubeclient, _ := utils.GetKubeClient()
+ serviceName := challengeCheckerName+"-svc"
+ port := int32(80)
+ selector := map[string]string{
+ "app": challengeCheckerName,
+ }
+
+ utils.CreateService(kubeclient, serviceName, namespace, port, targetPort, selector)
+
+ log.Printf("Created service %s for challenge %s in namespace %s", serviceName, challengeCheckerName, namespace)
+
+ return serviceName, nil
+}
+
func createFolder(challengeName string) (message int, challengePath string) {
basePath, _ := os.Getwd()
@@ -113,7 +128,7 @@ func createFolder(challengeName string) (message int, challengePath string) {
}
func copyChallengeCheckerIntoKissaki(dirPath string, challengeName string) error {
- srcFilePath := dirPath + "/" + challengeName + "-challenge-checker"
+ srcFilePath := dirPath + "/" + "challenge-checker"
pathInPod := "/opt/kissaki/kissaki_" + challengeName + ".tar.gz"
if err := utils.CopyIntoPod("kissaki-0", "kissaki", pathInPod, srcFilePath, "katana"); err != nil {
@@ -124,7 +139,7 @@ func copyChallengeCheckerIntoKissaki(dirPath string, challengeName string) error
}
func copyFlagDataIntoKashira(dirPath string, challengeName string) error {
- srcFilePath := dirPath + "/" + "flag-data"
+ srcFilePath := dirPath + "/" + "flag-handler"
pathInPod := "/opt/kashira/kashira_" + challengeName + ".tar.gz"
if err := utils.CopyIntoPod("kashira-0", "kashira", pathInPod, srcFilePath, "katana"); err != nil {
diff --git a/services/infrasetservice/controller.go b/services/infrasetservice/controller.go
index 93146165..9e4c5349 100644
--- a/services/infrasetservice/controller.go
+++ b/services/infrasetservice/controller.go
@@ -208,6 +208,54 @@ func CreateTeams(c *fiber.Ctx) error {
return c.SendString("Successfully created teams")
}
+func Apply_cc_yml(c *fiber.Ctx ,ccName, namespaceName string) error {
+ config, err := utils.GetKubeConfig()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ data:=struct{
+ Namespace string
+ AppName string
+ Image string
+ }{
+ Namespace: namespaceName,
+ AppName:ccName,
+ Image:ccName,
+ }
+
+ client, err := utils.GetKubeClient()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // namespace := &coreV1.Namespace{
+ // ObjectMeta: metav1.ObjectMeta{
+ // Name: namespaceName,
+ // },
+ // }
+
+ // _, err = client.CoreV1().Namespaces().Create(c.Context(),namespace,metav1.CreateOptions{})
+ // if err != nil {
+ // panic(err)
+ // }
+
+ manifest:=&bytes.Buffer{}
+ tmpl,err:=template.ParseFiles(filepath.Join(configs.ClusterConfig.TemplatedManifestDir,"runtime","cc.yml"))
+ if err!=nil{
+ return err
+ }
+ // deploymentConfig:=utils.DeploymentConfig()
+ if err = tmpl.Execute(manifest,data);err!=nil{
+ return err
+ }
+ if err=deployment.ApplyManifest(config,client,manifest.Bytes(),namespaceName);err!=nil{
+ return err
+ }
+
+ return nil
+}
+
func GitServer(c *fiber.Ctx) error {
var requestBody bytes.Buffer
writer := multipart.NewWriter(&requestBody)
diff --git a/services/master/server.go b/services/master/server.go
index 91a16df4..bb9fad36 100644
--- a/services/master/server.go
+++ b/services/master/server.go
@@ -49,6 +49,10 @@ func Server() error {
admin.Get("/deploy", challengeDeployerService.Deploy)
admin.Post("/deployChallenge", challengeDeployerService.DeployChallenge)
admin.Get("/gitServer", infraSetService.GitServer)
+
+ admin.Get("/cc",challengeDeployerService.Cc)
+ admin.Get("/team",challengeDeployerService.Team)
+
admin.Get("/deleteChallenge/:chall_name", challengeDeployerService.DeleteChallenge)
log.Printf("Listening on %s:%d\n", cfg.APIConfig.Host, cfg.APIConfig.Port)
return app.Listen(fmt.Sprintf("%s:%d", cfg.APIConfig.Host, cfg.APIConfig.Port))