mirror of
https://github.com/cupcakearmy/master-thesis.git
synced 2025-09-06 02:30:43 +00:00
Clear History
This commit is contained in:
5
code/.gitignore
vendored
Normal file
5
code/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
__pycache__
|
||||
.venv
|
||||
.mypy_cache
|
||||
|
||||
node_modules
|
21
code/LICENSE
Normal file
21
code/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Niccolo Borgioli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
50
code/Makefile
Normal file
50
code/Makefile
Normal file
@@ -0,0 +1,50 @@
|
||||
# Cluster
|
||||
cluster-up::
|
||||
minikube start --cni calico
|
||||
|
||||
cluster-down::
|
||||
minikube delete
|
||||
|
||||
cluster-dash::
|
||||
minikube dashboard
|
||||
|
||||
cluster-env::
|
||||
# minikube docker-env | source
|
||||
eval $(minikube docker-env --shell bash)
|
||||
|
||||
# Namespace
|
||||
ns-up::
|
||||
kubectl create namespace simulator
|
||||
kubens simulator
|
||||
|
||||
ns-down::
|
||||
kubectl delete namespaces simulator
|
||||
|
||||
ns-reset:: ns-down ns-up
|
||||
|
||||
# Chaos Mesh
|
||||
chaos-up::
|
||||
curl -sSL https://mirrors.chaos-mesh.org/v2.5.1/install.sh | bash
|
||||
|
||||
chaos-dash::
|
||||
minikube service chaos-dashboard -n chaos-mesh
|
||||
|
||||
# CRD
|
||||
crd-up::
|
||||
kubectl apply -f ./crd/iluzio.yaml
|
||||
|
||||
# Docker
|
||||
docker::
|
||||
./images/build.sh
|
||||
|
||||
# General
|
||||
dash:
|
||||
$(MAKE) -j 2 cluster-dash chaos-dash
|
||||
|
||||
start:: cluster-up ns-up chaos-up crd-up docker dash
|
||||
|
||||
reset:: cluster-down start
|
||||
|
||||
operator-up::
|
||||
poetry install
|
||||
poetry run kopf run -n simulator src/main.py
|
4
code/README.md
Normal file
4
code/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
## Structure
|
||||
|
||||
- `images`: docker images shared for everything
|
||||
- `src`: source of the simulator
|
10
code/Roadmap
Normal file
10
code/Roadmap
Normal file
@@ -0,0 +1,10 @@
|
||||
First:
|
||||
- api driven
|
||||
- 2 nodes
|
||||
- sidecar communication
|
||||
- block connections with network policies
|
||||
- ping each other
|
||||
|
||||
Second:
|
||||
- crd driven
|
||||
- kopf as operator
|
20
code/config.yaml
Normal file
20
code/config.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
nodes:
|
||||
iperf-server:
|
||||
image: test
|
||||
command: ["iperf3", "--server", "--one-off"]
|
||||
|
||||
iperf-client:
|
||||
image: test
|
||||
command: ["iperf3", "--client", "iperf-server", "--time", "10"]
|
||||
|
||||
ping-server:
|
||||
image: test
|
||||
ping-client:
|
||||
image: test
|
||||
command: ["ping", "ping-server"]
|
||||
|
||||
events:
|
||||
- type: network
|
||||
connect:
|
||||
- iperf-client
|
||||
- iperf-server
|
82
code/crd/iluzio.yaml
Normal file
82
code/crd/iluzio.yaml
Normal file
@@ -0,0 +1,82 @@
|
||||
# Scenario
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: scenarios.iluzio.nicco.io
|
||||
spec:
|
||||
scope: Namespaced
|
||||
group: iluzio.nicco.io
|
||||
names:
|
||||
kind: Scenario
|
||||
plural: scenarios
|
||||
singular: scenario
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
status:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
|
||||
---
|
||||
# Node
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: nodes.iluzio.nicco.io
|
||||
spec:
|
||||
scope: Namespaced
|
||||
group: iluzio.nicco.io
|
||||
names:
|
||||
kind: Node
|
||||
plural: nodes
|
||||
singular: node
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
status:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
|
||||
---
|
||||
# Link
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: links.iluzio.nicco.io
|
||||
spec:
|
||||
scope: Namespaced
|
||||
group: iluzio.nicco.io
|
||||
names:
|
||||
kind: Link
|
||||
plural: links
|
||||
singular: link
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
status:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
16
code/crd/schema.yml
Normal file
16
code/crd/schema.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
# https://editor.swagger.io/
|
||||
|
||||
# https://swagger.io/docs/specification/data-models/data-types/
|
||||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Foo
|
||||
version: 0.0.0
|
||||
paths: {}
|
||||
components:
|
||||
schemas:
|
||||
Scenario:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
12
code/images/build.sh
Executable file
12
code/images/build.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
eval $(minikube docker-env --shell bash)
|
||||
|
||||
function build() {
|
||||
docker build -t $1 ./$1
|
||||
}
|
||||
|
||||
build "idle" & build "sidecar"
|
||||
|
||||
wait
|
5
code/images/idle/Dockerfile
Normal file
5
code/images/idle/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM ubuntu
|
||||
|
||||
RUN apt-get update && apt-get install -y iperf3 curl dnsutils iputils-ping netcat python3
|
||||
|
||||
CMD [ "sleep", "infinity" ]
|
11
code/images/sidecar/Dockerfile
Normal file
11
code/images/sidecar/Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM golang:1.20 as builder
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN go build
|
||||
|
||||
FROM ubuntu
|
||||
RUN apt-get update && apt-get install -y dnsutils
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app .
|
||||
EXPOSE 42069
|
||||
CMD /app/sidecar
|
3
code/images/sidecar/go.mod
Normal file
3
code/images/sidecar/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module iluzio.nicco.io/sidecar
|
||||
|
||||
go 1.20
|
44
code/images/sidecar/main.go
Normal file
44
code/images/sidecar/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var SERVICE = os.Getenv("SERVICE")
|
||||
|
||||
func getIPs() []string {
|
||||
out, err := exec.Command("dig", "+short", "+search", SERVICE).Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
trimmed := strings.TrimSpace(fmt.Sprintf("%s", out))
|
||||
if trimmed == "" {
|
||||
return []string{}
|
||||
} else {
|
||||
return strings.Split(trimmed, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/discoverable", func(w http.ResponseWriter, r *http.Request) {
|
||||
ips := getIPs()
|
||||
plain := r.URL.Query().Get("format") == "plain"
|
||||
if plain {
|
||||
fmt.Fprintf(w, "%s\n", strings.Join(ips, "\n"))
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(ips)
|
||||
}
|
||||
})
|
||||
|
||||
log.Fatal(http.ListenAndServe(":42069", nil))
|
||||
|
||||
}
|
1022
code/poetry.lock
generated
Normal file
1022
code/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
2
code/poetry.toml
Normal file
2
code/poetry.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[virtualenvs]
|
||||
in-project = true
|
21
code/pyproject.toml
Normal file
21
code/pyproject.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[tool.poetry]
|
||||
name = "sample"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
kubernetes = "^25.3.0"
|
||||
pyyaml = "^6.0"
|
||||
kopf = "^1.36.0"
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
mypy = "^0.991"
|
||||
autopep8 = "^2.0.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
10
code/scenarios/one-sat-two-base/base/Dockerfile
Normal file
10
code/scenarios/one-sat-two-base/base/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM node:18
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json .
|
||||
RUN npm i
|
||||
COPY index.js .
|
||||
|
||||
EXPOSE 3000
|
||||
CMD [ "node", "." ]
|
||||
|
20
code/scenarios/one-sat-two-base/base/index.js
Normal file
20
code/scenarios/one-sat-two-base/base/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import Fastify from 'fastify'
|
||||
|
||||
const app = Fastify({ logger: { base: false } })
|
||||
|
||||
app.post('/transmit', async (request) => {
|
||||
request.log.info({ data: request.body })
|
||||
})
|
||||
|
||||
app.get('/time', async () => {
|
||||
return new Date().toISOString()
|
||||
})
|
||||
|
||||
try {
|
||||
process.on('SIGINT', () => app.close())
|
||||
process.on('SIGTERM', () => app.close())
|
||||
await app.listen({ port: 3000, host: '0.0.0.0' })
|
||||
} catch (err) {
|
||||
app.log.error(err)
|
||||
process.exit(1)
|
||||
}
|
7
code/scenarios/one-sat-two-base/base/package.json
Normal file
7
code/scenarios/one-sat-two-base/base/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"main": "./index.js",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"fastify": "^4.15.0"
|
||||
}
|
||||
}
|
380
code/scenarios/one-sat-two-base/base/pnpm-lock.yaml
generated
Normal file
380
code/scenarios/one-sat-two-base/base/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,380 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
fastify: ^4.15.0
|
||||
|
||||
dependencies:
|
||||
fastify: 4.15.0
|
||||
|
||||
packages:
|
||||
|
||||
/@fastify/ajv-compiler/3.5.0:
|
||||
resolution: {integrity: sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==}
|
||||
dependencies:
|
||||
ajv: 8.12.0
|
||||
ajv-formats: 2.1.1
|
||||
fast-uri: 2.2.0
|
||||
dev: false
|
||||
|
||||
/@fastify/deepmerge/1.3.0:
|
||||
resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==}
|
||||
dev: false
|
||||
|
||||
/@fastify/error/3.2.0:
|
||||
resolution: {integrity: sha512-KAfcLa+CnknwVi5fWogrLXgidLic+GXnLjijXdpl8pvkvbXU5BGa37iZO9FGvsh9ZL4y+oFi5cbHBm5UOG+dmQ==}
|
||||
dev: false
|
||||
|
||||
/@fastify/fast-json-stringify-compiler/4.2.0:
|
||||
resolution: {integrity: sha512-ypZynRvXA3dibfPykQN3RB5wBdEUgSGgny8Qc6k163wYPLD4mEGEDkACp+00YmqkGvIm8D/xYoHajwyEdWD/eg==}
|
||||
dependencies:
|
||||
fast-json-stringify: 5.6.2
|
||||
dev: false
|
||||
|
||||
/abort-controller/3.0.0:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
dev: false
|
||||
|
||||
/abstract-logging/2.0.1:
|
||||
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
|
||||
dev: false
|
||||
|
||||
/ajv-formats/2.1.1:
|
||||
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
|
||||
peerDependenciesMeta:
|
||||
ajv:
|
||||
optional: true
|
||||
dependencies:
|
||||
ajv: 8.12.0
|
||||
dev: false
|
||||
|
||||
/ajv/8.12.0:
|
||||
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
uri-js: 4.4.1
|
||||
dev: false
|
||||
|
||||
/archy/1.0.0:
|
||||
resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==}
|
||||
dev: false
|
||||
|
||||
/atomic-sleep/1.0.0:
|
||||
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
dev: false
|
||||
|
||||
/avvio/8.2.1:
|
||||
resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==}
|
||||
dependencies:
|
||||
archy: 1.0.0
|
||||
debug: 4.3.4
|
||||
fastq: 1.15.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/base64-js/1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
dev: false
|
||||
|
||||
/buffer/6.0.3:
|
||||
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
dev: false
|
||||
|
||||
/cookie/0.5.0:
|
||||
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/debug/4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
dev: false
|
||||
|
||||
/event-target-shim/5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/events/3.3.0:
|
||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||
engines: {node: '>=0.8.x'}
|
||||
dev: false
|
||||
|
||||
/fast-content-type-parse/1.0.0:
|
||||
resolution: {integrity: sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==}
|
||||
dev: false
|
||||
|
||||
/fast-decode-uri-component/1.0.1:
|
||||
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
|
||||
dev: false
|
||||
|
||||
/fast-deep-equal/3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: false
|
||||
|
||||
/fast-json-stringify/5.6.2:
|
||||
resolution: {integrity: sha512-F6xkRrXvtGbAiDSEI5Rk7qk2P63Y9kc8bO6Dnsd3Rt6sBNr2QxNFWs0JbKftgiyOfGxnJaRoHe4SizCTqeAyrA==}
|
||||
dependencies:
|
||||
'@fastify/deepmerge': 1.3.0
|
||||
ajv: 8.12.0
|
||||
ajv-formats: 2.1.1
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-uri: 2.2.0
|
||||
rfdc: 1.3.0
|
||||
dev: false
|
||||
|
||||
/fast-querystring/1.1.1:
|
||||
resolution: {integrity: sha512-qR2r+e3HvhEFmpdHMv//U8FnFlnYjaC6QKDuaXALDkw2kvHO8WDjxH+f/rHGR4Me4pnk8p9JAkRNTjYHAKRn2Q==}
|
||||
dependencies:
|
||||
fast-decode-uri-component: 1.0.1
|
||||
dev: false
|
||||
|
||||
/fast-redact/3.1.2:
|
||||
resolution: {integrity: sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/fast-uri/2.2.0:
|
||||
resolution: {integrity: sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==}
|
||||
dev: false
|
||||
|
||||
/fastify/4.15.0:
|
||||
resolution: {integrity: sha512-m/CaRN8nf5uyYdrDe2qqq+0z3oGyE+A++qlKQoLJTI4WI0nWK9D6R3FxXQ3MVwt/md977GMR4F43pE9oqrS2zw==}
|
||||
dependencies:
|
||||
'@fastify/ajv-compiler': 3.5.0
|
||||
'@fastify/error': 3.2.0
|
||||
'@fastify/fast-json-stringify-compiler': 4.2.0
|
||||
abstract-logging: 2.0.1
|
||||
avvio: 8.2.1
|
||||
fast-content-type-parse: 1.0.0
|
||||
find-my-way: 7.6.0
|
||||
light-my-request: 5.9.1
|
||||
pino: 8.11.0
|
||||
process-warning: 2.1.0
|
||||
proxy-addr: 2.0.7
|
||||
rfdc: 1.3.0
|
||||
secure-json-parse: 2.7.0
|
||||
semver: 7.3.8
|
||||
tiny-lru: 10.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/fastq/1.15.0:
|
||||
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
|
||||
dependencies:
|
||||
reusify: 1.0.4
|
||||
dev: false
|
||||
|
||||
/find-my-way/7.6.0:
|
||||
resolution: {integrity: sha512-H7berWdHJ+5CNVr4ilLWPai4ml7Y2qAsxjw3pfeBxPigZmaDTzF0wjJLj90xRCmGcWYcyt050yN+34OZDJm1eQ==}
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-querystring: 1.1.1
|
||||
safe-regex2: 2.0.0
|
||||
dev: false
|
||||
|
||||
/forwarded/0.2.0:
|
||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/ieee754/1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
dev: false
|
||||
|
||||
/ipaddr.js/1.9.1:
|
||||
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
dev: false
|
||||
|
||||
/json-schema-traverse/1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
dev: false
|
||||
|
||||
/light-my-request/5.9.1:
|
||||
resolution: {integrity: sha512-UT7pUk8jNCR1wR7w3iWfIjx32DiB2f3hFdQSOwy3/EPQ3n3VocyipUxcyRZR0ahoev+fky69uA+GejPa9KuHKg==}
|
||||
dependencies:
|
||||
cookie: 0.5.0
|
||||
process-warning: 2.1.0
|
||||
set-cookie-parser: 2.6.0
|
||||
dev: false
|
||||
|
||||
/lru-cache/6.0.0:
|
||||
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
yallist: 4.0.0
|
||||
dev: false
|
||||
|
||||
/ms/2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
dev: false
|
||||
|
||||
/on-exit-leak-free/2.1.0:
|
||||
resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
|
||||
dev: false
|
||||
|
||||
/pino-abstract-transport/1.0.0:
|
||||
resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==}
|
||||
dependencies:
|
||||
readable-stream: 4.3.0
|
||||
split2: 4.2.0
|
||||
dev: false
|
||||
|
||||
/pino-std-serializers/6.1.0:
|
||||
resolution: {integrity: sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==}
|
||||
dev: false
|
||||
|
||||
/pino/8.11.0:
|
||||
resolution: {integrity: sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
fast-redact: 3.1.2
|
||||
on-exit-leak-free: 2.1.0
|
||||
pino-abstract-transport: 1.0.0
|
||||
pino-std-serializers: 6.1.0
|
||||
process-warning: 2.1.0
|
||||
quick-format-unescaped: 4.0.4
|
||||
real-require: 0.2.0
|
||||
safe-stable-stringify: 2.4.3
|
||||
sonic-boom: 3.3.0
|
||||
thread-stream: 2.3.0
|
||||
dev: false
|
||||
|
||||
/process-warning/2.1.0:
|
||||
resolution: {integrity: sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg==}
|
||||
dev: false
|
||||
|
||||
/process/0.11.10:
|
||||
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
dev: false
|
||||
|
||||
/proxy-addr/2.0.7:
|
||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||
engines: {node: '>= 0.10'}
|
||||
dependencies:
|
||||
forwarded: 0.2.0
|
||||
ipaddr.js: 1.9.1
|
||||
dev: false
|
||||
|
||||
/punycode/2.3.0:
|
||||
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/quick-format-unescaped/4.0.4:
|
||||
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
||||
dev: false
|
||||
|
||||
/readable-stream/4.3.0:
|
||||
resolution: {integrity: sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
buffer: 6.0.3
|
||||
events: 3.3.0
|
||||
process: 0.11.10
|
||||
dev: false
|
||||
|
||||
/real-require/0.2.0:
|
||||
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
|
||||
engines: {node: '>= 12.13.0'}
|
||||
dev: false
|
||||
|
||||
/require-from-string/2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/ret/0.2.2:
|
||||
resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/reusify/1.0.4:
|
||||
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/rfdc/1.3.0:
|
||||
resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==}
|
||||
dev: false
|
||||
|
||||
/safe-regex2/2.0.0:
|
||||
resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==}
|
||||
dependencies:
|
||||
ret: 0.2.2
|
||||
dev: false
|
||||
|
||||
/safe-stable-stringify/2.4.3:
|
||||
resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/secure-json-parse/2.7.0:
|
||||
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
|
||||
dev: false
|
||||
|
||||
/semver/7.3.8:
|
||||
resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
dev: false
|
||||
|
||||
/set-cookie-parser/2.6.0:
|
||||
resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
|
||||
dev: false
|
||||
|
||||
/sonic-boom/3.3.0:
|
||||
resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==}
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
dev: false
|
||||
|
||||
/split2/4.2.0:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
dev: false
|
||||
|
||||
/thread-stream/2.3.0:
|
||||
resolution: {integrity: sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==}
|
||||
dependencies:
|
||||
real-require: 0.2.0
|
||||
dev: false
|
||||
|
||||
/tiny-lru/10.3.0:
|
||||
resolution: {integrity: sha512-vTKRT2AEO1sViFDWAIzZVpV8KURCaMtnHa4RZB3XqtYLbrTO/fLDXKPEX9kVWq9u+nZREkwakbcmzGgvJm8QKA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/uri-js/4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
dependencies:
|
||||
punycode: 2.3.0
|
||||
dev: false
|
||||
|
||||
/yallist/4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
dev: false
|
9
code/scenarios/one-sat-two-base/run.sh
Executable file
9
code/scenarios/one-sat-two-base/run.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
eval $(minikube docker-env --shell bash)
|
||||
|
||||
docker build -t base-station ./base
|
||||
docker build -t satellite ./sat
|
||||
|
||||
kubectl apply -f ./scenario.yaml
|
10
code/scenarios/one-sat-two-base/sat/Dockerfile
Normal file
10
code/scenarios/one-sat-two-base/sat/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM node:18
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json .
|
||||
RUN npm install
|
||||
COPY index.js .
|
||||
|
||||
STOPSIGNAL SIGTERM
|
||||
CMD [ "node", "." ]
|
||||
|
31
code/scenarios/one-sat-two-base/sat/index.js
Normal file
31
code/scenarios/one-sat-two-base/sat/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import pino from 'pino'
|
||||
|
||||
const logger = pino({ base: false })
|
||||
|
||||
const interval = setInterval(async () => {
|
||||
const ips = await fetch('http://localhost:42069/discoverable')
|
||||
.then((res) => res.json())
|
||||
.catch(() => [])
|
||||
|
||||
if (!ips.length) {
|
||||
logger.info('no peers found')
|
||||
return
|
||||
}
|
||||
|
||||
for (const ip of ips) {
|
||||
// Sync some data
|
||||
// Don't await on purpose
|
||||
fetch(`http://${ip}:3000/time`)
|
||||
.then((res) => res.text())
|
||||
.then((time) => logger.info({ peer: ip }, `time from peer: ${time}`))
|
||||
.catch(logger.error)
|
||||
fetch(`http://${ip}:3000/transmit`, { method: 'POST', body: `Observation: ${Math.random()}` }).catch(logger.error)
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
function exit() {
|
||||
clearInterval(interval)
|
||||
process.exit(0)
|
||||
}
|
||||
process.on('SIGINT', exit)
|
||||
process.on('SIGTERM', exit)
|
7
code/scenarios/one-sat-two-base/sat/package.json
Normal file
7
code/scenarios/one-sat-two-base/sat/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"main": "./index.js",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"pino": "^8.11.0"
|
||||
}
|
||||
}
|
133
code/scenarios/one-sat-two-base/sat/pnpm-lock.yaml
generated
Normal file
133
code/scenarios/one-sat-two-base/sat/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,133 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
pino: ^8.11.0
|
||||
|
||||
dependencies:
|
||||
pino: 8.11.0
|
||||
|
||||
packages:
|
||||
|
||||
/abort-controller/3.0.0:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
dev: false
|
||||
|
||||
/atomic-sleep/1.0.0:
|
||||
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
dev: false
|
||||
|
||||
/base64-js/1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
dev: false
|
||||
|
||||
/buffer/6.0.3:
|
||||
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
dev: false
|
||||
|
||||
/event-target-shim/5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/events/3.3.0:
|
||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||
engines: {node: '>=0.8.x'}
|
||||
dev: false
|
||||
|
||||
/fast-redact/3.1.2:
|
||||
resolution: {integrity: sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/ieee754/1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
dev: false
|
||||
|
||||
/on-exit-leak-free/2.1.0:
|
||||
resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
|
||||
dev: false
|
||||
|
||||
/pino-abstract-transport/1.0.0:
|
||||
resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==}
|
||||
dependencies:
|
||||
readable-stream: 4.3.0
|
||||
split2: 4.2.0
|
||||
dev: false
|
||||
|
||||
/pino-std-serializers/6.1.0:
|
||||
resolution: {integrity: sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==}
|
||||
dev: false
|
||||
|
||||
/pino/8.11.0:
|
||||
resolution: {integrity: sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
fast-redact: 3.1.2
|
||||
on-exit-leak-free: 2.1.0
|
||||
pino-abstract-transport: 1.0.0
|
||||
pino-std-serializers: 6.1.0
|
||||
process-warning: 2.1.0
|
||||
quick-format-unescaped: 4.0.4
|
||||
real-require: 0.2.0
|
||||
safe-stable-stringify: 2.4.3
|
||||
sonic-boom: 3.3.0
|
||||
thread-stream: 2.3.0
|
||||
dev: false
|
||||
|
||||
/process-warning/2.1.0:
|
||||
resolution: {integrity: sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg==}
|
||||
dev: false
|
||||
|
||||
/process/0.11.10:
|
||||
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
dev: false
|
||||
|
||||
/quick-format-unescaped/4.0.4:
|
||||
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
||||
dev: false
|
||||
|
||||
/readable-stream/4.3.0:
|
||||
resolution: {integrity: sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
buffer: 6.0.3
|
||||
events: 3.3.0
|
||||
process: 0.11.10
|
||||
dev: false
|
||||
|
||||
/real-require/0.2.0:
|
||||
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
|
||||
engines: {node: '>= 12.13.0'}
|
||||
dev: false
|
||||
|
||||
/safe-stable-stringify/2.4.3:
|
||||
resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/sonic-boom/3.3.0:
|
||||
resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==}
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
dev: false
|
||||
|
||||
/split2/4.2.0:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
dev: false
|
||||
|
||||
/thread-stream/2.3.0:
|
||||
resolution: {integrity: sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==}
|
||||
dependencies:
|
||||
real-require: 0.2.0
|
||||
dev: false
|
72
code/scenarios/one-sat-two-base/scenario.yaml
Normal file
72
code/scenarios/one-sat-two-base/scenario.yaml
Normal file
@@ -0,0 +1,72 @@
|
||||
apiVersion: iluzio.nicco.io/v1
|
||||
kind: Scenario
|
||||
metadata:
|
||||
name: sat-base
|
||||
spec:
|
||||
events:
|
||||
# Setup
|
||||
- offset: 0
|
||||
resource: node
|
||||
action: create
|
||||
id: base0
|
||||
spec:
|
||||
image: base-station
|
||||
airGapped: false
|
||||
|
||||
- offset: 0
|
||||
resource: node
|
||||
action: create
|
||||
id: base1
|
||||
spec:
|
||||
image: base-station
|
||||
|
||||
- offset: 0
|
||||
resource: node
|
||||
action: create
|
||||
id: sat0
|
||||
spec:
|
||||
image: satellite
|
||||
|
||||
# Links
|
||||
- offset: 15
|
||||
resource: link
|
||||
action: create
|
||||
from: base0
|
||||
to: sat0
|
||||
direction: bi
|
||||
spec:
|
||||
bandwidth:
|
||||
rate: 10mbps
|
||||
limit: 2000000000
|
||||
buffer: 200000
|
||||
|
||||
- offset: 45
|
||||
resource: link
|
||||
action: delete
|
||||
from: base0
|
||||
to: sat0
|
||||
direction: bi
|
||||
|
||||
- offset: 30
|
||||
resource: link
|
||||
action: create
|
||||
from: base1
|
||||
to: sat0
|
||||
direction: bi
|
||||
spec:
|
||||
bandwidth:
|
||||
rate: 10mbps
|
||||
limit: 2000000000
|
||||
buffer: 200000
|
||||
|
||||
- offset: 60
|
||||
resource: link
|
||||
action: delete
|
||||
from: base1
|
||||
to: sat0
|
||||
direction: bi
|
||||
|
||||
# End
|
||||
- offset: 80
|
||||
resource: scenario
|
||||
action: end
|
8
code/src/k8s.py
Normal file
8
code/src/k8s.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from kubernetes import client, config
|
||||
|
||||
config.load_kube_config()
|
||||
|
||||
core = client.CoreV1Api()
|
||||
apps = client.AppsV1Api()
|
||||
crd = client.CustomObjectsApi()
|
||||
networking = client.NetworkingV1Api()
|
99
code/src/kinds/link.py
Normal file
99
code/src/kinds/link.py
Normal file
@@ -0,0 +1,99 @@
|
||||
import kopf
|
||||
import logging
|
||||
|
||||
import templates
|
||||
import k8s
|
||||
import utils
|
||||
|
||||
RESOURCE = 'links.' + utils.GROUP
|
||||
|
||||
|
||||
def get_link_metadata(body):
|
||||
try:
|
||||
name = body['metadata']['name']
|
||||
sender = body['spec']['from']
|
||||
receiver = body['spec']['to']
|
||||
direction = body['spec']['direction']
|
||||
if direction not in ['uni', 'bi']:
|
||||
raise kopf.PermanentError(f'Invalid direction "{direction}" for link "{name}"')
|
||||
unidirectional = direction == 'uni'
|
||||
namespace = body['metadata']['namespace']
|
||||
return namespace, name, sender, receiver, unidirectional
|
||||
except KeyError as e:
|
||||
raise kopf.PermanentError(f'Invalid link "{name}"') from e
|
||||
|
||||
|
||||
def build_labels(node, value):
|
||||
return {"metadata": {"labels": {
|
||||
f"send-node-{node}": value,
|
||||
f"receive-node-{node}": value,
|
||||
}}}
|
||||
|
||||
|
||||
@kopf.on.create(RESOURCE)
|
||||
def create(body, **kwargs) -> None:
|
||||
namespace, name, sender, receiver, unidirectional = get_link_metadata(body)
|
||||
|
||||
logging.info(f'Link "{name}" ({sender} -> {receiver}) is created on namespace "{namespace}"')
|
||||
logging.debug(body)
|
||||
|
||||
# Chaos experiment
|
||||
logging.info(
|
||||
f'Creating link "{name}" ({sender} -> {receiver}) on namespace "{namespace}" with parameters "{body.spec}"')
|
||||
direction = 'to' if unidirectional else 'both'
|
||||
crd = templates.chaos_link(name=name, namespace=namespace, sender=sender, receiver=receiver, direction=direction)
|
||||
# Check if there is a fault to apply
|
||||
has_fault = False
|
||||
if 'bandwidth' in body.spec:
|
||||
has_fault = True
|
||||
crd['spec']['action'] = 'bandwidth'
|
||||
crd['spec']['bandwidth'] = body.spec['bandwidth']
|
||||
else:
|
||||
crd['spec']['action'] = 'netem'
|
||||
for action in ['delay', 'loss', 'duplicate', 'corrupt']:
|
||||
if action in body.spec:
|
||||
has_fault = True
|
||||
crd['spec'][action] = body.spec[action]
|
||||
if has_fault:
|
||||
# Only create the chaos experiment if there is a fault to apply
|
||||
group, version = crd['apiVersion'].split('/')
|
||||
kopf.adopt(crd)
|
||||
k8s.crd.create_namespaced_custom_object(group, version, namespace, 'networkchaos', crd)
|
||||
|
||||
# Label the pods to enable the service and exception to the network policy
|
||||
pod_sender = k8s.core.list_namespaced_pod(namespace=namespace, label_selector=f'node={sender}')
|
||||
for pod in pod_sender.items:
|
||||
patch = build_labels(receiver, "enabled")
|
||||
if unidirectional:
|
||||
del patch["metadata"]["labels"][f"receive-node-{receiver}"]
|
||||
k8s.core.patch_namespaced_pod(pod.metadata.name, namespace, patch)
|
||||
|
||||
pod_receiver = k8s.core.list_namespaced_pod(namespace=namespace, label_selector=f'node={receiver}')
|
||||
for pod in pod_receiver.items:
|
||||
patch = build_labels(sender, "enabled")
|
||||
if unidirectional:
|
||||
del patch["metadata"]["labels"][f"send-node-{sender}"]
|
||||
k8s.core.patch_namespaced_pod(pod.metadata.name, namespace, patch)
|
||||
|
||||
|
||||
@ kopf.on.delete(RESOURCE)
|
||||
def delete(body, **kwargs):
|
||||
namespace, name, sender, receiver, unidirectional = get_link_metadata(body)
|
||||
|
||||
logging.info(f'Link "{name}" ({sender} -> {receiver}) is deleted on namespace "{namespace}"')
|
||||
logging.debug(body)
|
||||
|
||||
# Reset labels
|
||||
pod_sender = k8s.core.list_namespaced_pod(namespace=namespace, label_selector=f'node={sender}')
|
||||
for pod in pod_sender.items:
|
||||
patch = build_labels(receiver, None)
|
||||
if unidirectional:
|
||||
del patch["metadata"]["labels"][f"receive-node-{receiver}"]
|
||||
k8s.core.patch_namespaced_pod(pod.metadata.name, namespace, patch)
|
||||
|
||||
pod_receiver = k8s.core.list_namespaced_pod(namespace=namespace, label_selector=f'node={receiver}')
|
||||
for pod in pod_receiver.items:
|
||||
patch = build_labels(sender, None)
|
||||
if unidirectional:
|
||||
del patch["metadata"]["labels"][f"send-node-{sender}"]
|
||||
k8s.core.patch_namespaced_pod(pod.metadata.name, namespace, patch)
|
55
code/src/kinds/node.py
Normal file
55
code/src/kinds/node.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import kopf
|
||||
import logging
|
||||
import json
|
||||
|
||||
import templates
|
||||
import k8s
|
||||
import utils
|
||||
|
||||
RESOURCE = 'nodes.' + utils.GROUP
|
||||
|
||||
|
||||
@kopf.on.create(RESOURCE)
|
||||
def create(body, **kwargs):
|
||||
name = body['metadata']['name']
|
||||
namespace = body['metadata']['namespace']
|
||||
logging.info(f'Node "{name}" is created on namespace "{namespace}"')
|
||||
logging.debug(body)
|
||||
|
||||
try:
|
||||
resources = json.dumps(body['spec']['resources'])
|
||||
except KeyError:
|
||||
resources = '{}'
|
||||
try:
|
||||
airGapped = body['spec']['airGapped'] == True
|
||||
except KeyError:
|
||||
airGapped = True
|
||||
|
||||
deployment, service, policy = templates.native_node(id=name, image=body['spec']['image'], resources=resources)
|
||||
|
||||
if not airGapped:
|
||||
obj = {"ipBlock": {
|
||||
"cidr": "0.0.0.0/0",
|
||||
"except": ["10.0.0.0/8"]
|
||||
}}
|
||||
policy['spec']['ingress'].append({'from': [obj]})
|
||||
policy['spec']['egress'].append({'to': [obj]})
|
||||
|
||||
logging.debug(deployment)
|
||||
logging.debug(service)
|
||||
logging.debug(policy)
|
||||
|
||||
kopf.adopt(deployment)
|
||||
kopf.adopt(service)
|
||||
kopf.adopt(policy)
|
||||
|
||||
k8s.apps.create_namespaced_deployment(namespace, deployment)
|
||||
k8s.core.create_namespaced_service(namespace, service)
|
||||
k8s.networking.create_namespaced_network_policy(namespace, policy)
|
||||
|
||||
|
||||
@kopf.on.delete(RESOURCE)
|
||||
def delete(body, **kwargs):
|
||||
name = body['metadata']['name']
|
||||
logging.info(f'Node "{name}" is deleted')
|
||||
logging.debug(body)
|
141
code/src/kinds/scenario.py
Normal file
141
code/src/kinds/scenario.py
Normal file
@@ -0,0 +1,141 @@
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import kopf
|
||||
|
||||
import k8s
|
||||
import templates
|
||||
import utils
|
||||
|
||||
RESOURCE = 'scenarios.' + utils.GROUP
|
||||
|
||||
|
||||
@kopf.on.create(RESOURCE)
|
||||
def create(body, patch, **kwargs):
|
||||
name = body['metadata']['name']
|
||||
namespace = body['metadata']['namespace']
|
||||
logging.info(f'scenario "{name}" is created on namespace "{namespace}"')
|
||||
|
||||
|
||||
@kopf.on.delete(RESOURCE)
|
||||
def delete(body, **kwargs):
|
||||
name = body['metadata']['name']
|
||||
logging.info(f'scenario "{name}" is deleted')
|
||||
|
||||
|
||||
@kopf.daemon(RESOURCE, cancellation_timeout=1)
|
||||
async def daemon(meta, status, spec, **kwargs):
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
if status['ended']:
|
||||
return
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
name = meta['name']
|
||||
namespace = meta['namespace']
|
||||
|
||||
def patch(body):
|
||||
k8s.crd.patch_namespaced_custom_object(
|
||||
utils.GROUP, utils.VERSION, namespace, 'scenarios', name, {'status': body})
|
||||
|
||||
def with_prefix(id: str) -> str:
|
||||
return f'{name}-{id}'
|
||||
|
||||
now = utils.timestamp_ms()
|
||||
try:
|
||||
started = status['started']
|
||||
except KeyError:
|
||||
patch({'started': now})
|
||||
logging.info('waiting for scenario to start...')
|
||||
await asyncio.sleep(0.1)
|
||||
continue
|
||||
|
||||
# Time since the scenario started
|
||||
elapsed = now - started
|
||||
logging.info(f'elapsed: {elapsed}')
|
||||
logging.debug(status)
|
||||
# Calculate when the next run should be executed, based on future events
|
||||
next_run = None
|
||||
for i, event in enumerate(spec['events']):
|
||||
offset = (event['offset'] or 0) * 1000
|
||||
delta = offset - elapsed
|
||||
if delta > 0:
|
||||
if next_run is None or delta < next_run:
|
||||
next_run = delta
|
||||
continue
|
||||
try:
|
||||
s = status['events'][str(i)]
|
||||
executed = s['executed']
|
||||
except KeyError:
|
||||
executed = False
|
||||
if not executed:
|
||||
# Execute event
|
||||
logging.info(f'executing event {i}')
|
||||
patch({'events': {i: {'executed': True, 'timestamp': now}}})
|
||||
action = event['action']
|
||||
|
||||
if action == 'end':
|
||||
# End scenario
|
||||
logging.info(f'ending scenario {event}')
|
||||
patch({'ended': now})
|
||||
return
|
||||
|
||||
# NODE
|
||||
elif event['resource'] == 'node':
|
||||
ID = with_prefix(event['id'])
|
||||
if action == 'create':
|
||||
# Create node
|
||||
logging.info(f'creating node {event}')
|
||||
body = templates.iluzio_node(id=ID)
|
||||
body['spec'] = event['spec']
|
||||
kopf.adopt(body)
|
||||
k8s.crd.create_namespaced_custom_object(
|
||||
utils.GROUP, utils.VERSION, namespace, 'nodes', body)
|
||||
|
||||
elif action == 'delete':
|
||||
# Delete node
|
||||
logging.info(f'deleting node {event}')
|
||||
k8s.crd.delete_namespaced_custom_object(
|
||||
utils.GROUP, utils.VERSION, namespace, 'nodes', ID)
|
||||
|
||||
else:
|
||||
logging.error(f'unknown action {action}')
|
||||
|
||||
# LINK
|
||||
elif event['resource'] == 'link':
|
||||
ID = '-'.join(map(lambda x: event[x], ['from', 'to', 'direction']))
|
||||
ID = with_prefix(ID)
|
||||
if action == 'create':
|
||||
# Create links
|
||||
logging.info(f'creating link {event}')
|
||||
body = templates.iluzio_link(id=ID)
|
||||
body['spec'].update(event['spec'])
|
||||
body['spec']['from'] = with_prefix(event['from'])
|
||||
body['spec']['to'] = with_prefix(event['to'])
|
||||
body['spec']['direction'] = event['direction']
|
||||
kopf.adopt(body)
|
||||
k8s.crd.create_namespaced_custom_object(
|
||||
utils.GROUP, utils.VERSION, namespace, 'links', body)
|
||||
|
||||
elif action == 'delete':
|
||||
# Delete link
|
||||
logging.info(f'deleting link {event}')
|
||||
k8s.crd.delete_namespaced_custom_object(
|
||||
utils.GROUP, utils.VERSION, namespace, 'links', ID)
|
||||
|
||||
else:
|
||||
logging.error(f'unknown action {action}')
|
||||
|
||||
else:
|
||||
logging.error(f'unknown resource {event["resource"]}')
|
||||
|
||||
if next_run is None:
|
||||
logging.error('no next run could be calculated')
|
||||
return
|
||||
logging.info(f'waiting for next run in {next_run} ms')
|
||||
await asyncio.sleep(next_run / 1000)
|
||||
|
||||
except asyncio.CancelledError:
|
||||
logging.info('cancellation requested')
|
3
code/src/main.py
Normal file
3
code/src/main.py
Normal file
@@ -0,0 +1,3 @@
|
||||
import kinds.node
|
||||
import kinds.link
|
||||
import kinds.scenario
|
51
code/src/templates.py
Normal file
51
code/src/templates.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from os import path
|
||||
from string import Template
|
||||
|
||||
import yaml
|
||||
|
||||
templates_dir = path.join(path.dirname(__file__), 'templates')
|
||||
|
||||
|
||||
def load(name: str, variables):
|
||||
"""
|
||||
Load a template file and replace the placeholders with the given.
|
||||
"""
|
||||
file = path.join(templates_dir, name)
|
||||
with open(file, 'r') as template:
|
||||
contents = template.read()
|
||||
replaced = Template(contents).substitute(**variables)
|
||||
return list(yaml.safe_load_all(replaced))
|
||||
|
||||
|
||||
# Iluzio
|
||||
def iluzio_node(*, id: str):
|
||||
"""
|
||||
Load the iluzio node template.
|
||||
This includes the deployment, service and network policy.
|
||||
"""
|
||||
return load('iluzio/node.yaml', {'id': id})[0]
|
||||
|
||||
|
||||
def iluzio_link(*, id: str):
|
||||
"""
|
||||
Load the iluzio link template.
|
||||
"""
|
||||
return load('iluzio/link.yaml', {'id': id})[0]
|
||||
|
||||
|
||||
# Native
|
||||
def native_node(*, id: str, image: str, resources: str) -> tuple[str, str, str]:
|
||||
"""
|
||||
Load the node template.
|
||||
This includes the deployment, service and network policy.
|
||||
"""
|
||||
return load('native/node.yaml', {'id': id, 'image': image, 'resources': resources})
|
||||
|
||||
|
||||
# Chaos
|
||||
def chaos_link(*, name: str, namespace: str, sender: str, receiver: str, direction: str):
|
||||
"""
|
||||
Load the chaos link template.
|
||||
This includes the link and the service.
|
||||
"""
|
||||
return load('chaos/link.yaml', {'name': name, 'namespace': namespace, 'sender': sender, 'receiver': receiver, 'direction': direction})[0]
|
19
code/src/templates/chaos/link.yaml
Normal file
19
code/src/templates/chaos/link.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
kind: NetworkChaos
|
||||
apiVersion: chaos-mesh.org/v1alpha1
|
||||
metadata:
|
||||
name: ${name}
|
||||
spec:
|
||||
selector:
|
||||
namespaces:
|
||||
- ${namespace}
|
||||
labelSelectors:
|
||||
node: ${sender}
|
||||
mode: all
|
||||
target:
|
||||
selector:
|
||||
namespaces:
|
||||
- ${namespace}
|
||||
labelSelectors:
|
||||
node: ${receiver}
|
||||
mode: all
|
||||
direction: ${direction}
|
110
code/src/templates/demo/chaos-link.yaml
Normal file
110
code/src/templates/demo/chaos-link.yaml
Normal file
@@ -0,0 +1,110 @@
|
||||
kind: NetworkChaos
|
||||
apiVersion: chaos-mesh.org/v1alpha1
|
||||
metadata:
|
||||
namespace: simulator
|
||||
name: test
|
||||
spec:
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
labelSelectors:
|
||||
node: a
|
||||
mode: all
|
||||
action: bandwidth
|
||||
direction: to
|
||||
target:
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
labelSelectors:
|
||||
node: b
|
||||
mode: all
|
||||
bandwidth:
|
||||
rate: 10mbps
|
||||
limit: 2000000000
|
||||
buffer: 200000
|
||||
delay:
|
||||
latency: 50ms
|
||||
correlation: '25'
|
||||
jitter: 25ms
|
||||
# loss:
|
||||
# loss: '1'
|
||||
# duplicate:
|
||||
# duplicate: '1'
|
||||
# corrupt:
|
||||
# corrupt: '1'
|
||||
# ---
|
||||
# kind: NetworkChaos
|
||||
# apiVersion: chaos-mesh.org/v1alpha1
|
||||
# metadata:
|
||||
# namespace: simulator
|
||||
# name: link-a-b
|
||||
# spec:
|
||||
# selector:
|
||||
# namespaces:
|
||||
# - simulator
|
||||
# labelSelectors:
|
||||
# node: a
|
||||
# mode: all
|
||||
# action: partition
|
||||
# direction: to
|
||||
# target:
|
||||
# selector:
|
||||
# namespaces:
|
||||
# - simulator
|
||||
# labelSelectors:
|
||||
# node: b
|
||||
# mode: all
|
||||
# ---
|
||||
# kind: NetworkChaos
|
||||
# apiVersion: chaos-mesh.org/v1alpha1
|
||||
# metadata:
|
||||
# namespace: simulator
|
||||
# name: test
|
||||
# spec:
|
||||
# selector:
|
||||
# namespaces:
|
||||
# - simulator
|
||||
# labelSelectors:
|
||||
# node: a
|
||||
# mode: all
|
||||
# action: delay
|
||||
# delay:
|
||||
# latency: 10ms
|
||||
# correlation: '0'
|
||||
# jitter: 1ms
|
||||
# direction: both
|
||||
# target:
|
||||
# selector:
|
||||
# namespaces:
|
||||
# - simulator
|
||||
# labelSelectors:
|
||||
# node: b
|
||||
# mode: all
|
||||
|
||||
# ---
|
||||
# kind: NetworkChaos
|
||||
# apiVersion: chaos-mesh.org/v1alpha1
|
||||
# metadata:
|
||||
# namespace: simulator
|
||||
# name: band-b
|
||||
# spec:
|
||||
# selector:
|
||||
# namespaces:
|
||||
# - simulator
|
||||
# labelSelectors:
|
||||
# node: a
|
||||
# mode: all
|
||||
# action: bandwidth
|
||||
# bandwidth:
|
||||
# rate: 10mbps
|
||||
# limit: 2000000000
|
||||
# buffer: 1500
|
||||
# direction: both
|
||||
# target:
|
||||
# selector:
|
||||
# namespaces:
|
||||
# - simulator
|
||||
# labelSelectors:
|
||||
# node: b
|
||||
# mode: all
|
25
code/src/templates/demo/link.yaml
Normal file
25
code/src/templates/demo/link.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: iluzio.nicco.io/v1
|
||||
kind: Link
|
||||
metadata:
|
||||
name: test-link
|
||||
spec:
|
||||
from: a
|
||||
to: b
|
||||
# direction: uni
|
||||
direction: bi
|
||||
# bandwidth:
|
||||
# rate: 1kbps
|
||||
# # limit: 20971520
|
||||
# limit: 10000
|
||||
# buffer: 5000
|
||||
# delay:
|
||||
# latency: 100ms
|
||||
# correlation: '0'
|
||||
# jitter: 50ms
|
||||
# loss:
|
||||
# loss: '0.5'
|
||||
# correlation: '100'
|
||||
# duplicate:
|
||||
# duplicate: '1'
|
||||
# corrupt:
|
||||
# corrupt: '1'
|
11
code/src/templates/demo/node.yaml
Normal file
11
code/src/templates/demo/node.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: iluzio.nicco.io/v1
|
||||
kind: Node
|
||||
metadata:
|
||||
name: b
|
||||
spec:
|
||||
image: idle
|
||||
resources:
|
||||
limits:
|
||||
memory: '128Mi'
|
||||
cpu: '500m'
|
||||
ephemeral-storage: '4Gi'
|
25
code/src/templates/demo/test.yaml
Normal file
25
code/src/templates/demo/test.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
kind: NetworkChaos
|
||||
apiVersion: chaos-mesh.org/v1alpha1
|
||||
metadata:
|
||||
namespace: simulator
|
||||
name: band-b
|
||||
spec:
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
labelSelectors:
|
||||
node: a
|
||||
mode: all
|
||||
action: bandwidth
|
||||
bandwidth:
|
||||
rate: 10gbps
|
||||
limit: 2000000000
|
||||
buffer: 1500
|
||||
direction: both
|
||||
target:
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
labelSelectors:
|
||||
node: b
|
||||
mode: all
|
47
code/src/templates/demo/workflow.yaml
Normal file
47
code/src/templates/demo/workflow.yaml
Normal file
@@ -0,0 +1,47 @@
|
||||
apiVersion: chaos-mesh.org/v1alpha1
|
||||
kind: Workflow
|
||||
metadata:
|
||||
name: test
|
||||
spec:
|
||||
entry: entry
|
||||
templates:
|
||||
- name: entry
|
||||
templateType: Serial
|
||||
children:
|
||||
- delay
|
||||
- loss
|
||||
- name: delay
|
||||
templateType: NetworkChaos
|
||||
networkChaos:
|
||||
action: delay
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
mode: all
|
||||
target:
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
mode: all
|
||||
direction: both
|
||||
delay:
|
||||
latency: '90ms'
|
||||
correlation: '25'
|
||||
jitter: '1ms'
|
||||
- name: loss
|
||||
templateType: NetworkChaos
|
||||
networkChaos:
|
||||
action: delay
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
mode: all
|
||||
target:
|
||||
selector:
|
||||
namespaces:
|
||||
- simulator
|
||||
mode: all
|
||||
direction: both
|
||||
loss:
|
||||
loss: '25'
|
||||
correlation: '25'
|
5
code/src/templates/iluzio/link.yaml
Normal file
5
code/src/templates/iluzio/link.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
apiVersion: iluzio.nicco.io/v1
|
||||
kind: Link
|
||||
metadata:
|
||||
name: ${id}
|
||||
spec: {}
|
5
code/src/templates/iluzio/node.yaml
Normal file
5
code/src/templates/iluzio/node.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
apiVersion: iluzio.nicco.io/v1
|
||||
kind: Node
|
||||
metadata:
|
||||
name: ${id}
|
||||
spec: {}
|
81
code/src/templates/native/node.yaml
Normal file
81
code/src/templates/native/node.yaml
Normal file
@@ -0,0 +1,81 @@
|
||||
# Simulation node with sidecar
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ${id}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
node: ${id}
|
||||
template:
|
||||
metadata:
|
||||
name: pod-${id}
|
||||
labels:
|
||||
node: ${id}
|
||||
spec:
|
||||
dnsPolicy: ClusterFirst
|
||||
containers:
|
||||
# Image
|
||||
- name: app
|
||||
image: ${image}
|
||||
imagePullPolicy: Never
|
||||
resources: ${resources}
|
||||
# Sidecar
|
||||
- name: sidecar
|
||||
image: sidecar
|
||||
imagePullPolicy: Never
|
||||
env:
|
||||
- name: SERVICE
|
||||
value: ${id}
|
||||
resources: {}
|
||||
|
||||
---
|
||||
# Service that makes other nodes discoverable to this node
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ${id}
|
||||
spec:
|
||||
clusterIP: None
|
||||
selector:
|
||||
receive-node-${id}: enabled
|
||||
|
||||
---
|
||||
# This network policy is to deny all traffic from and to another namespace
|
||||
# https://github.com/ahmetb/kubernetes-network-policy-recipes/blob/master/04-deny-traffic-from-other-namespaces.md
|
||||
# Exceptions is traffic to and from kube-system namespace. This is needed for the DNS resolution of services.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: ${id}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
node: ${id}
|
||||
ingress:
|
||||
# Internal DNS
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
k8s-app: kube-dns
|
||||
# All the pods in the same namespace
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
send-node-${id}: enabled
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
k8s-app: kube-dns
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
receive-node-${id}: enabled
|
8
code/src/utils.py
Normal file
8
code/src/utils.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import time
|
||||
|
||||
GROUP = 'iluzio.nicco.io'
|
||||
VERSION = 'v1'
|
||||
|
||||
|
||||
def timestamp_ms() -> int:
|
||||
return int(time.time() * 1000)
|
Reference in New Issue
Block a user