
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth1
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br1",
      "mtu": 1400,
      "device": "veth1"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth2
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br2",
      "mtu": 1400,
      "device": "veth2"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth3
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br3",
      "mtu": 1400,
      "device": "veth3"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth4
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br4",
      "mtu": 1400,
      "device": "veth4"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth5
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br5",
      "mtu": 1400,
      "device": "veth5"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth6
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br6",
      "mtu": 1400,
      "device": "veth6"
    }'
---

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth7
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br7",
      "mtu": 1400,
      "device": "veth7"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth8
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br8",
      "mtu": 1400,
      "device": "veth8"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth9
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br9",
      "mtu": 1400,
      "device": "veth9"
    }'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: veth10
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "bridge",
      "bridge": "br10",
      "mtu": 1400,
      "device": "veth10"
    }'
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: l2sm-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: l2sm-operator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: l2sm-operator
    namespace: default
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: l2sm-controller
spec:
  replicas: 1
  selector:
    matchLabels:
      app: l2sm-controller
  template:
    metadata:
      labels:
        app: l2sm-controller
    spec:
      containers:
      - name: l2sm-controller
        image: alexdecb/l2sm-controller:2.2
        readinessProbe:
          httpGet:
            path: /onos/ui
            port: 8181   
          initialDelaySeconds: 30
          periodSeconds: 10
        ports:
        - containerPort: 6633
        - containerPort: 8181
---
apiVersion: v1
kind: Service
metadata:
  name: l2sm-controller-service
spec:
  selector:
    app: l2sm-controller
  ports:
  - name: of13-port
    protocol: TCP
    port: 6633
    targetPort: 6633
  - name: http-port
    protocol: TCP
    port: 8181
    targetPort: 8181
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: l2sm-operator
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      l2sm-component: l2sm-opt
  template:
    metadata:
      labels:
        l2sm-component: l2sm-opt
    spec:
      serviceAccountName: l2sm-operator
      initContainers:
      - name: wait-for-l2sm-controller
        image: curlimages/curl
        args:
        - /bin/sh
        - -c
        - >
          set -x;
          while [ $(curl -sw '%{http_code}' "http://l2sm-controller-service:8181/onos/ui" -o /dev/null) -ne 302 ]; do
            sleep 15;
          done;
          sleep 5;
      containers:
      - image: alexdecb/l2sm-operator:2.3
        name: l2sm-opt-pod
        env:
          - name: CONTROLLER_IP
            value: l2sm-controller-service
        #imagePullPolicy: Always
      - name: mysql
        image: mysql:5.7
        envFrom:
        - secretRef:
            name: mysql-secret
        ports:
          - containerPort: 3306
            name: mysql
        volumeMounts:
          - name: mysql-persistent-storage
            mountPath: /var/lib/mysql
          - name: initdb-volume
            mountPath: /docker-entrypoint-initdb.d
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-pv-claim
        - name: initdb-volume
          configMap:
            name: mysql-schema
            items:
            - key: init.sql
              path: init.sql
      nodeSelector:
        dedicated: master
      tolerations:
      - key: dedicated
        operator: Equal
        value: master
        effect: NoSchedule
        
---
apiVersion: v1
kind: Service
metadata:
  name: l2sm-operator-service
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  selector:
    l2sm-component: l2sm-opt
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-schema
data:
  init.sql: |
  
    CREATE DATABASE IF NOT EXISTS l2sm;
    USE l2sm;

    CREATE TABLE networks (
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(255) NOT NULL,
      type ENUM('vlink', 'vnet', 'ext-vnet') NOT NULL,
      UNIQUE KEY unique_network_name (name, type)
    );

    CREATE TABLE switches (
      id INT PRIMARY KEY AUTO_INCREMENT,
      node_name VARCHAR(255) NOT NULL,
      openflowId TEXT,
      ip VARCHAR(15)
    );

    CREATE TABLE neds (
      id INT PRIMARY KEY AUTO_INCREMENT,
      node_name VARCHAR(255) NOT NULL,
      provider VARCHAR(255) NOT NULL,
      openflowId TEXT,
      ip VARCHAR(15)
    );

    CREATE TABLE interfaces (
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(255),
      pod VARCHAR(255),
      switch_id INT,
      ned_id INT,
      network_id INT,
      FOREIGN KEY (switch_id) REFERENCES switches(id),
      FOREIGN KEY (ned_id) REFERENCES neds(id),
      FOREIGN KEY (network_id) REFERENCES networks(id)
    );

    -- Define the one-to-many relationship between switches and interfaces
    ALTER TABLE interfaces
    ADD CONSTRAINT fk_switch_interface
    FOREIGN KEY (switch_id)
    REFERENCES switches(id);

    -- Define the one-to-many relationship between neds and interfaces
    ALTER TABLE interfaces
    ADD CONSTRAINT fk_ned_interface
    FOREIGN KEY (ned_id)
    REFERENCES neds(id);

    -- Define the many-to-one relationship between networks and interfaces
    ALTER TABLE interfaces
    ADD CONSTRAINT fk_network_interface
    FOREIGN KEY (network_id)
    REFERENCES networks(id);
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: l2sm-switch
  #namespace: kube-system
  labels:
    l2sm-component: l2sm-switch
spec:
  selector:
    matchLabels:
      l2sm-component: l2sm-switch
  template:
    metadata:
      labels:
        l2sm-component: l2sm-switch
      annotations:
        k8s.v1.cni.cncf.io/networks: veth1, veth2, veth3, veth4, veth5, veth6, veth7, veth8, veth9, veth10
    spec:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can't run pods
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      initContainers:
      - name: wait-for-l2sm-operator
        image: curlimages/curl
        args:
        - /bin/sh
        - -c
        - >
          set -x;
          while [ $(curl -sw '%{http_code}' "http://l2sm-operator-service:8080/healthz" -o /dev/null) -ne 200 ]; do
            sleep 15;
          done;
          sleep 5;
      containers:
      - name: l2sm-switch
        image: alexdecb/l2sm-switch:2.2
        #args: ["setup_switch.sh && sleep infinity"]
        env:
        - name: NODENAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: NVETHS
          value: "10"  
        - name: CONTROLLERIP
          value: "l2sm-controller-service"
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]
      nodeSelector:
        kubernetes.io/arch: amd64
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: l2sm-networks.l2sm.k8s.local
spec:
  group: l2sm.k8s.local
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                type:
                  type: string
                config:
                  type: string 
                  nullable: true
                signature:
                  type: string
                  nullable: true
            status:
              type: object
              properties:
                connectedPods:
                  type: array
                  items:
                    type: string
  scope: Namespaced
  names:
    plural: l2sm-networks
    singular: l2sm-network
    kind: L2SMNetwork
    shortNames:
      - l2sm-net

