Giter Site home page Giter Site logo

kub8-api's People

Contributors

anasjaghoub avatar black996 avatar mabumusa1 avatar mlahlouh avatar salemcode8 avatar

Watchers

 avatar  avatar  avatar

kub8-api's Issues

Create install does not respect sizes

At the current code base when we want to create, copy, or move an install the creation process does not respect the size of the pod to be created based on the subscription size, this needs to be changed and the YAML must be changed to accommodate the pod size changes.

This is how the request is being interpreted by the system

    id: schema.string({}, [rules.regex(/^[a-z0-9_-]*$/)]),
    env_type: schema.enum(['dev', 'stg', 'prd'] as const),
    size: schema.enum(['s1', 's2', 's3', 's4', 's5', 'custom'] as const),
    domain: schema.string({}, [
      rules.regex(/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/),
    ]),
    region: schema.string.optional(),
    custom: schema.object.optional([rules.requiredWhen('size', '=', 'custom')]).members({
      cpu: schema.number([rules.range(1, 40)]), //TODO: Implement validation for specific type so of CPU
      memory: schema.number([rules.range(1, 32)]), //TODO: Implement validation for specific type of memory
    }),
  })


database structure for tracking internal operations

operation_metadata table:
metadata for each endpoint and its stages

operation_metadata      
api method operation op_sequence
install post create_mysql_user 1
install post create_mysql_db 2
install post grant_user 3
install post create_statefulSet 4
install post create_service 5
install post create_certificate 6
install post create_ingress 7
       
varchar varchar varchar int

operation_log table:
log for each stage/client with status, in case of failure, should rollback all previous operations

operation_log              
client_id api method operation started_ts end_ts status  
iab install post create_mysql_user 1 2 sucess rollback
iab install post create_mysql_db 2 3 success rollback
iab install post grant_user 3 4 fail rollback
iab install post create_statefulSet 4 5    
iab install post create_service 5 6    
iab install post create_certificate        
iab install post create_ingress        
               
varchar varchar varchar varchar timestamp timestamp enum('started', 'success', 'fail', 'rollback')  

@mabumusa1

Create Install

To create a new Install we need to call 4 times,

  1. Create StatefulSet
  2. Create Service
  3. Create Certificate
  4. Create Ingress

Example: https://github.com/kubernetes-client/javascript/blob/ea5041dda50f1fd772fd66c058421fca98853f64/examples/ingress.js#L8

in below example for a client called: tadamon

all variables contains tadamon should be passed as a parameter

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: tadamon
spec:
  selector:
    matchLabels:
      app: tadamon-mautic # has to match .spec.template.metadata.labels
  serviceName: "tadamon-service"
  replicas: 1 # by default is 1
  template:
    metadata:
      labels:
        app: tadamon-mautic # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: tadamon-container
        image: 407780391754.dkr.ecr.ap-south-1.amazonaws.com/mautic_sc:latest
        env:
        - name: MAUTIC_DB_USER
          value: "tadamon_user"
        - name: MAUTIC_DB_PASSWORD
          value: "123456789"
        - name: MAUTIC_DB_NAME
          value: "tadamon"
        - name: MAUTIC_DB_HOST
          value: "db.internal"
        - name: client-name
          value: "tadamon"        
        ports:
        - containerPort: 80
          name: tadamon
        volumeMounts:
        - name: tadamon-claim
          mountPath: /code      
        tty: true
        workingDir: /code
      restartPolicy: Always          
  volumeClaimTemplates:
  - metadata:
      name: tadamon-claim
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "gp2"
      resources:
        requests:
          storage: 10Gi  
apiVersion: v1
kind: Service
metadata:
  name: tadamon-service
  namespace: default
  labels:
    app: tadamon-mautic
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: tadamon-mautic
  type: ClusterIP
  sessionAffinity: None
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: tadamon-secret
  namespace: default
spec:
  dnsNames:
    - tadamon.steercampaign.com
  issuerRef:
    group: cert-manager.io
    kind: ClusterIssuer
    name: letsencrypt-prod-ingress
  secretName: tadamon-secret
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tadamon-ingress
  namespace: default
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod-ingress
status:
  loadBalancer:
    ingress:
      - hostname: >-
          a91db86aaa6a947ae8cf9a0ee09c740a-1073567115.ap-south-1.elb.amazonaws.com
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - tadamon.steercampaign.com
      secretName: tadamon-secret
  rules:
    - host: tadamon.steercampaign.com
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              service:
                name: tadamon-service
                port:
                  number: 80

Show formatted error messages

Right now we are using the default response of API from AdonisJS, we want to have the response to formatted as

{
error: error,
message: 'message'
}

Enable dry run

We need to have a dry run on all the operations before they run.

Responses Curl

Sample Success request:

ubuntu@ip-172-31-28-109:~$ curl http://localhost:8001/apis/apps/v1/namespaces/default/statefulsets -k -H "Content-Type: application/yaml" -XPOST -d '
> apiVersion: apps/v1
> kind: StatefulSet
> metadata:
>   name: tadamon
> spec:
>   selector:
>     matchLabels:
>       app: tadamon-mautic # has to match .spec.template.metadata.labels
>   serviceName: "tadamon-service"
>   replicas: 1 # by default is 1
>   template:
>     metadata:
>       labels:
>         app: tadamon-mautic # has to match .spec.selector.matchLabels
>     spec:
>       terminationGracePeriodSeconds: 10
        - name: MAUTIC_DB_NAME
          value: "tadamon"
        - name: MAUTIC_DB_HOST
          value: "db.internal"
        - name: client-name
          value: "tadamon"
        ports:
        - containerPort: 80
          name: tadamon
        volumeMounts:
        - name: tadamon-claim
          mountPath: /code
        tty: true
        workingDir: /code
      restartPolicy: Always
  volumeClaimTemplates:
>       containers:
>       - name: tadamon-container
>         image: nginx
>         env:
>         - name: MAUTIC_DB_USER
>           value: "tadamon_user"
>         - name: MAUTIC_DB_PASSWORD
>           value: "QAZ2wsx3edc4rfv"
>         - name: MAUTIC_DB_NAME
>           value: "tadamon"
>         - name: MAUTIC_DB_HOST
>           value: "db.internal"
>         - name: client-name
>           value: "tadamon"
>         ports:
>         - containerPort: 80
>           name: tadamon
>         volumeMounts:
>         - name: tadamon-claim
>           mountPath: /code
>         tty: true
>         workingDir: /code
>       restartPolicy: Always
>   volumeClaimTemplates:
>   - metadata:
>       name: tadamon-claim
>     spec:
>       accessModes: [ "ReadWriteOnce" ]
>       storageClassName: "gp2"
>       resources:
>         requests:
>           storage: 10Gi  '
{
  "kind": "StatefulSet",
  "apiVersion": "apps/v1",
  "metadata": {
    "name": "tadamon",
    "namespace": "default",
    "uid": "48e29310-999b-41d4-b4e9-6b8cd3a13098",
    "resourceVersion": "2367870",
    "generation": 1,
    "creationTimestamp": "2022-03-27T12:01:08Z",
    "managedFields": [
      {
        "manager": "curl",
        "operation": "Update",
        "apiVersion": "apps/v1",
        "time": "2022-03-27T12:01:08Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {
          "f:spec": {
            "f:podManagementPolicy": {},
            "f:replicas": {},
            "f:revisionHistoryLimit": {},
            "f:selector": {},
            "f:serviceName": {},
            "f:template": {
              "f:metadata": {
                "f:labels": {
                  ".": {},
                  "f:app": {}
                }
              },
              "f:spec": {
                "f:containers": {
                  "k:{\"name\":\"tadamon-container\"}": {
                    ".": {},
                    "f:env": {
                      ".": {},
                      "k:{\"name\":\"MAUTIC_DB_HOST\"}": {
                        ".": {},
                        "f:name": {},
                        "f:value": {}
                      },
                      "k:{\"name\":\"MAUTIC_DB_NAME\"}": {
                        ".": {},
                        "f:name": {},
                        "f:value": {}
                      },
                      "k:{\"name\":\"MAUTIC_DB_PASSWORD\"}": {
                        ".": {},
                        "f:name": {},
                        "f:value": {}
                      },
                      "k:{\"name\":\"MAUTIC_DB_USER\"}": {
                        ".": {},
                        "f:name": {},
                        "f:value": {}
                      },
                      "k:{\"name\":\"client-name\"}": {
                        ".": {},
                        "f:name": {},
                        "f:value": {}
                      }
                    },
                    "f:image": {},
                    "f:imagePullPolicy": {},
                    "f:name": {},
                    "f:ports": {
                      ".": {},
                      "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": {
                        ".": {},
                        "f:containerPort": {},
                        "f:name": {},
                        "f:protocol": {}
                      }
                    },
                    "f:resources": {},
                    "f:terminationMessagePath": {},
                    "f:terminationMessagePolicy": {},
                    "f:tty": {},
                    "f:volumeMounts": {
                      ".": {},
                      "k:{\"mountPath\":\"/code\"}": {
                        ".": {},
                        "f:mountPath": {},
                        "f:name": {}
                      }
                    },
                    "f:workingDir": {}
                  }
                },
                "f:dnsPolicy": {},
                "f:restartPolicy": {},
                "f:schedulerName": {},
                "f:securityContext": {},
                "f:terminationGracePeriodSeconds": {}
              }
            },
            "f:updateStrategy": {
              "f:rollingUpdate": {
                ".": {},
                "f:partition": {}
              },
              "f:type": {}
            },
            "f:volumeClaimTemplates": {}
          }
        }
      }
    ]
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "app": "tadamon-mautic"
      }
    },
    "template": {
      "metadata": {
        "creationTimestamp": null,
        "labels": {
          "app": "tadamon-mautic"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "tadamon-container",
            "image": "nginx",
            "workingDir": "/code",
            "ports": [
              {
                "name": "tadamon",
                "containerPort": 80,
                "protocol": "TCP"
              }
            ],
            "env": [
              {
                "name": "MAUTIC_DB_USER",
                "value": "tadamon_user"
              },
              {
                "name": "MAUTIC_DB_PASSWORD",
                "value": "QAZ2wsx3edc4rfv"
              },
              {
                "name": "MAUTIC_DB_NAME",
                "value": "tadamon"
              },
              {
                "name": "MAUTIC_DB_HOST",
                "value": "db.internal"
              },
              {
                "name": "client-name",
                "value": "tadamon"
              }
            ],
            "resources": {},
            "volumeMounts": [
              {
                "name": "tadamon-claim",
                "mountPath": "/code"
              }
            ],
            "terminationMessagePath": "/dev/termination-log",
            "terminationMessagePolicy": "File",
            "imagePullPolicy": "Always",
            "tty": true
          }
        ],
        "restartPolicy": "Always",
        "terminationGracePeriodSeconds": 10,
        "dnsPolicy": "ClusterFirst",
        "securityContext": {},
        "schedulerName": "default-scheduler"
      }
    },
    "volumeClaimTemplates": [
      {
        "kind": "PersistentVolumeClaim",
        "apiVersion": "v1",
        "metadata": {
          "name": "tadamon-claim",
          "creationTimestamp": null
        },
        "spec": {
          "accessModes": [
            "ReadWriteOnce"
          ],
          "resources": {
            "requests": {
              "storage": "10Gi"
            }
          },
          "storageClassName": "gp2",
          "volumeMode": "Filesystem"
        },
        "status": {
          "phase": "Pending"
        }
      }
    ],
    "serviceName": "tadamon-service",
    "podManagementPolicy": "OrderedReady",
    "updateStrategy": {
      "type": "RollingUpdate",
      "rollingUpdate": {
        "partition": 0
      }
    },
    "revisionHistoryLimit": 10
  },
  "status": {
    "replicas": 0,
    "availableReplicas": 0
  }
}ubuntu@ip-172-31-28-109:~$

Sample error "AlreadyExists"

ubuntu@ip-172-31-28-109:~$ curl http://localhost:8001/apis/apps/v1/namespaces/default/statefulsets -k -H "Content-Type: application/yaml" -XPOST -d '
> apiVersion: apps/v1
> kind: StatefulSet
> metadata:
>   name: tadamon
> spec:
>   selector:
        - name: MAUTIC_DB_HOST
          value: "db.internal"
        - name: client-name
          value: "tadamon"
        ports:
        - containerPort: 80
          name: tadamon
        volumeMounts:
>     matchLabels:
>       app: tadamon-mautic # has to match .spec.template.metadata.labels
>   serviceName: "tadamon-service"
>   replicas: 1 # by default is 1
>   template:
>     metadata:
>       labels:
>         app: tadamon-mautic # has to match .spec.selector.matchLabels
>     spec:
>       terminationGracePeriodSeconds: 10
>       containers:
>       - name: tadamon-container
>         image: nginx
>         env:
>         - name: MAUTIC_DB_USER
>           value: "tadamon_user"
>         - name: MAUTIC_DB_PASSWORD
>           value: "QAZ2wsx3edc4rfv"
>         - name: MAUTIC_DB_NAME
>           value: "tadamon"
>         - name: MAUTIC_DB_HOST
>           value: "db.internal"
>         - name: client-name
>           value: "tadamon"
>         ports:
>         - containerPort: 80
>           name: tadamon
>         volumeMounts:
>         - name: tadamon-claim
>           mountPath: /code
>         tty: true
>         workingDir: /code
>       restartPolicy: Always
>   volumeClaimTemplates:
>   - metadata:
>       name: tadamon-claim
>     spec:
>       accessModes: [ "ReadWriteOnce" ]
>       storageClassName: "gp2"
>       resources:
>         requests:
>           storage: 10Gi  '
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "statefulsets.apps \"tadamon\" already exists",
  "reason": "AlreadyExists",
  "details": {
    "name": "tadamon",
    "group": "apps",
    "kind": "statefulsets"
  },
  "code": 409
}ubuntu@ip-172-31-28-109:~$

Dynamic Cluster information

Right now the cluster information is stored as an environment variable which makes the code base fixed to one Ku8 Cluster which is our own Kub8 cluster (the shared one), this will not be the case when we have an enterprise cluster that will have its own variables.

We need to make changes to the code base to be like this:

  1. Has a database(not necessarily a relational database) of the available clusters with their information, and this node js application will query the database and get the cluster info based on the incoming request.
  2. Store cluster information in the laravel database and send the information with each request to nodejs to be implemented

Let's discuss this and move with the best approach

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.