diff --git a/docs/swagger-test.yaml b/docs/swagger-test.yaml deleted file mode 100644 index f9dc8841..00000000 --- a/docs/swagger-test.yaml +++ /dev/null @@ -1,7638 +0,0 @@ -openapi: 3.0.0 -info: - title: Datasance PoT Controller - version: 3.5.0 - description: Datasance PoT Controller REST API Documentation -servers: - - url: http://localhost:51121/api/v3 -tags: - - name: Controller - description: Manage your controller - - name: ioFog - description: Manage your agents - - name: Application - description: Manage your applications - - name: Application Template - description: Manage your application templates - - name: Catalog - description: Manage your catalog - - name: Registries - description: Manage your registries - - name: Microservices - description: Manage your microservices - - name: Routing - description: Manage your routes - - name: Router - description: Manage your Default Router - - name: Edge Resource - description: Manage your Edge Resources - - name: Diagnostics - description: Diagnostic your microservices - - name: Tunnel - description: Manage ssh tunnels - - name: Agent - description: Used by your agents to communicate with your controller - - name: User - description: Manage your users - - name: Secrets - description: Manage your secrets - - name: Certificates - description: Manage your certificates - - name: Services - description: Manage your services - - name: VolumeMounts - description: Manage your volume mounts - - name: ConfigMap - description: Manage your config maps -components: - securitySchemes: - authToken: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT token for authentication (user or agent) - schemas: - image: - type: object - properties: - containerImage: - type: string - fogTypeId: - type: integer - minimum: 1 - maximum: 2 - required: - - containerImage - - fogTypeId - volumeMappings: - type: object - properties: - hostDestination: - type: string - containerDestination: - type: string - accessMode: - type: string - type: - enum: - - volume - - bind - required: - - hostDestination - - containerDestination - - accessMode - ports: - type: object - properties: - internal: - type: integer - external: - type: integer - protocol: - enum: - - tcp - - udp - required: - - internal - - external - extraHosts: - type: object - properties: - name: - type: string - address: - type: string - required: - - name - - address - env: - type: object - properties: - key: - type: string - value: - type: string - valueFromSecret: - type: string - valueFromConfigMap: - type: string - required: - - key - oneOf: - - required: - - value - - required: - - valueFromSecret - - required: - - valueFromConfigMap - straceData: - type: object - properties: - microserviceUuid: - type: string - buffer: - type: string - required: - - microserviceUuid - - buffer - microserviceStatus: - type: object - properties: - id: - type: string - containerId: - type: string - status: - type: string - startTime: - type: integer - operatingDuration: - type: integer - cpuUsage: - type: number - memoryUsage: - type: number - ipAddress: - type: string - ipAddressExternal: - type: string - execSessionIds: - type: array - items: - type: string - required: - - id - agentProvision: - type: object - properties: - type: - type: integer - minimum: 0 - maximum: 2 - key: - type: string - required: - - type - - key - agentDeprovision: - type: object - properties: - microserviceUuids: - type: array - items: - type: string - required: - - microserviceUuids - updateAgentConfig: - type: object - properties: - networkInterface: - type: string - dockerUrl: - type: string - diskLimit: - type: integer - minimum: 0 - diskDirectory: - type: string - memoryLimit: - type: integer - minimum: 0 - cpuLimit: - type: integer - minimum: 0 - logLimit: - type: integer - minimum: 0 - logDirectory: - type: string - logFileCount: - type: integer - minimum: 0 - statusFrequency: - type: integer - minimum: 0 - changeFrequency: - type: integer - minimum: 0 - deviceScanFrequency: - type: integer - minimum: 0 - watchdogEnabled: - type: boolean - latitude: - type: number - minimum: -90 - maximum: 90 - longitude: - type: number - minimum: -180 - maximum: 180 - gpsMode: - type: string - gpsDevice: - type: string - gpsScanFrequency: - type: integer - minimum: 0 - edgeGuardFrequency: - type: integer - minimum: 0 - dockerPruningFrequency: - type: integer - minimum: 0 - availableDiskThreshold: - type: integer - minimum: 0 - logLevel: - type: string - timeZone: - type: string - updateAgentStatus: - type: object - properties: - daemonStatus: - type: string - warningMessage: - type: string - daemonOperatingDuration: - type: integer - minimum: 0 - daemonLastStart: - type: integer - minimum: 0 - memoryUsage: - type: number - minimum: 0 - diskUsage: - type: number - minimum: 0 - cpuUsage: - type: number - minimum: 0 - memoryViolation: - type: boolean - diskViolation: - type: boolean - cpuViolation: - type: boolean - systemAvailableDisk: - type: integer - systemAvailableMemory: - type: integer - systemTotalCpu: - type: number - securityStatus: - type: string - securityViolationInfo: - type: string - microserviceStatus: - type: string - repositoryCount: - type: integer - minimum: 0 - repositoryStatus: - type: string - systemTime: - type: integer - minimum: 0 - lastStatusTime: - type: integer - minimum: 0 - ipAddress: - type: string - ipAddressExternal: - type: string - processedMessages: - type: integer - minimum: 0 - microserviceMessageCounts: - type: string - messageSpeed: - type: number - minimum: 0 - lastCommandTime: - type: integer - minimum: 0 - gpsMode: - type: string - gpsDevice: - type: string - gpsScanFrequency: - type: integer - minimum: 0 - edgeGuardFrequency: - type: integer - minimum: 0 - tunnelStatus: - type: string - version: - type: string - isReadyToUpgrade: - type: boolean - isReadyToRollback: - type: boolean - updateAgentStrace: - type: object - properties: - straceData: - type: array - items: - $ref: '#/components/schemas/straceData' - updateHardwareInfo: - type: object - properties: - info: - type: string - required: - - info - updateUsbInfo: - type: object - properties: - info: - type: string - required: - - info - applicationTemplateVariable: - type: object - properties: - key: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - description: - type: string - required: - - key - applicationTemplateCreate: - type: object - properties: - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - description: - type: string - variables: - type: array - items: - $ref: '#/components/schemas/applicationTemplateVariable' - required: - - name - applicationTemplateUpdate: - type: object - properties: - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - description: - type: string - applicationJSON: - $ref: '#/components/schemas/applicationCreate' - variables: - type: array - items: - $ref: '#/components/schemas/applicationTemplateVariable' - applicationTemplatePatch: - type: object - properties: - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - description: - type: string - applicationTemplateDeploy: - type: object - properties: - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - description: - type: string - isActivated: - type: boolean - isSystem: - type: boolean - variables: - type: array - items: - type: object - properties: - key: - type: string - value: - type: string - required: - - name - applicationCreate: - type: object - properties: - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - routes: - type: array - items: - $ref: '#/components/schemas/routingCreate' - microservices: - type: array - items: - $ref: '#/components/schemas/microserviceCreate' - description: - type: string - isActivated: - type: boolean - isSystem: - type: boolean - required: - - name - applicationUpdate: - type: object - properties: - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - microservices: - type: array - items: - $ref: '#/components/schemas/microserviceCreate' - routes: - type: array - items: - $ref: '#/components/schemas/routingCreate' - description: - type: string - isActivated: - type: boolean - isSystem: - type: boolean - applicationPatch: - type: object - properties: - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - description: - type: string - isActivated: - type: boolean - isSystem: - type: boolean - type: - type: object - properties: - infoType: - type: string - infoFormat: - type: string - catalogItemCreate: - type: object - properties: - name: - type: string - minLength: 1 - description: - type: string - category: - type: string - publisher: - type: string - diskRequired: - type: integer - ramRequired: - type: integer - picture: - type: string - isPublic: - type: boolean - registryId: - type: integer - configExample: - type: string - images: - type: array - minItems: 1 - maxItems: 2 - items: - $ref: '#/components/schemas/image' - inputType: - $ref: '#/components/schemas/type' - outputType: - $ref: '#/components/schemas/type' - required: - - name - - registryId - - images - catalogItemUpdate: - type: object - properties: - name: - type: string - minLength: 1 - description: - type: string - category: - type: string - publisher: - type: string - diskRequired: - type: integer - ramRequired: - type: integer - picture: - type: string - isPublic: - type: boolean - registryId: - type: integer - configExample: - type: string - images: - type: array - maxItems: 2 - items: - $ref: '#/components/schemas/image' - inputType: - $ref: '#/components/schemas/type' - outputType: - $ref: '#/components/schemas/type' - caCreate: - type: object - properties: - name: - type: string - minLength: 1 - maxLength: 255 - subject: - type: string - minLength: 1 - expiration: - type: integer - minimum: 0 - type: - type: string - enum: - - k8s-secret - - direct - - self-signed - secretName: - type: string - required: - - type - - name - allOf: - - {} - - {} - certificateCreate: - type: object - properties: - name: - type: string - minLength: 1 - maxLength: 255 - subject: - type: string - minLength: 1 - hosts: - type: string - minLength: 1 - expiration: - type: integer - minimum: 0 - ca: - type: object - properties: - type: - type: string - enum: - - k8s-secret - - direct - - self-signed - secretName: - type: string - required: - - type - required: - - name - - subject - - hosts - caResponse: - type: object - properties: - name: - type: string - subject: - type: string - type: - type: string - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - name - - subject - - type - - created_at - - updated_at - certificateResponse: - type: object - properties: - name: - type: string - subject: - type: string - hosts: - type: string - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - name - - subject - - hosts - - created_at - - updated_at - caListResponse: - type: object - properties: - cas: - type: array - items: - type: object - properties: - name: - type: string - subject: - type: string - type: - type: string - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - name - - subject - - type - - created_at - - updated_at - required: - - cas - certificateListResponse: - type: object - properties: - certificates: - type: array - items: - type: object - properties: - name: - type: string - subject: - type: string - hosts: - type: string - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - name - - subject - - hosts - - created_at - - updated_at - required: - - certificates - configMapCreate: - type: object - properties: - name: - type: string - minLength: 1 - maxLength: 255 - immutable: - type: boolean - data: - type: object - required: - - name - - data - configMapUpdate: - type: object - properties: - immutable: - type: boolean - data: - type: object - required: - - data - configMapResponse: - type: object - properties: - id: - type: integer - name: - type: string - immutable: - type: boolean - data: - type: object - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - id - - name - - data - - created_at - - updated_at - configMapListResponse: - type: object - properties: - configMaps: - type: array - items: - type: object - properties: - id: - type: integer - name: - type: string - immutable: - type: boolean - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - id - - name - - created_at - - updated_at - required: - - configMaps - configUpdate: - type: object - properties: - port: - type: integer - minimum: 0 - maximum: 65535 - sslCert: - type: string - sslKey: - type: string - intermediateCert: - type: string - logDir: - type: string - logSize: - type: integer - configElement: - type: object - properties: - key: - type: string - minLength: 1 - value: - type: string - required: - - key - - value - profile: - type: object - properties: {} - straceStateUpdate: - type: object - properties: - enable: - type: boolean - required: - - enable - straceGetData: - type: object - properties: - format: - enum: - - string - - file - required: - - format - stracePostToFtp: - type: object - properties: - ftpHost: - type: string - ftpPort: - type: integer - minimum: 0 - ftpUser: - type: string - ftpPass: - type: string - ftpDestDir: - type: string - required: - - ftpHost - - ftpPort - - ftpUser - - ftpPass - - ftpDestDir - edgeResourceDisplay: - type: object - properties: - name: - type: string - color: - type: string - pattern: ^(#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8}))|(rgb(s*(?:(d{1,3})s*,?){3}))|(rgba(s*(?:(d{1,3})s*,?){4}))|$ - icon: - type: string - edgeResourceHTTPEndpoint: - type: object - properties: - name: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - description: - type: string - method: - enum: - - GET - - POST - - PUT - - PATCH - - DELETE - - HEAD - - OPTIONS - url: - type: string - requestType: - type: string - responseType: - type: string - requestPayloadExample: - type: string - responsePayloadExample: - type: string - edgeResource: - type: object - properties: - display: - $ref: '#/components/schemas/edgeResourceDisplay' - name: - type: string - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - version: - type: string - minLength: 1 - pattern: ^v?(0|[1-9]d*).(0|[1-9]d*).(0|[1-9]d*)(?:-((?:0|[1-9]d*|d*[a-zA-Z-][0-9a-zA-Z-]*)(?:.(?:0|[1-9]d*|d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:[+]([0-9a-zA-Z-]+(?:.[0-9a-zA-Z-]+)*))?$ - description: - type: string - orchestrationTags: - type: array - items: - type: string - interfaceProtocol: - enum: - - http - - https - - ws - - wss - oneOf: - - properties: - interfaceProtocol: - enum: - - http - - https - - ws - - wss - interface: - type: object - properties: - endpoints: - type: array - items: - $ref: /edgeResourceHTTPEndpoint - edgeResourceCreate: - type: object - allOf: - - $ref: '#/components/schemas/edgeResource' - required: - - name - - version - edgeResourceUpdate: - type: object - allOf: - - $ref: '#/components/schemas/edgeResource' - filter: - type: object - properties: - key: - type: string - value: - type: string - condition: - enum: - - has - - equals - required: - - key - - value - - condition - iofogTag: - type: string - iofogCreate: - type: object - properties: - name: - type: string - minLength: 1 - location: - type: string - latitude: - type: number - minimum: -90 - maximum: 90 - longitude: - type: number - minimum: -180 - maximum: 180 - description: - type: string - networkInterface: - type: string - dockerUrl: - type: string - containerEngine: - type: string - enum: - - docker - - podman - deploymentType: - type: string - enum: - - native - - container - diskLimit: - type: integer - minimum: 0 - diskDirectory: - type: string - memoryLimit: - type: integer - minimum: 0 - cpuLimit: - type: integer - minimum: 0 - logLimit: - type: integer - minimum: 0 - logDirectory: - type: string - logFileCount: - type: integer - minimum: 0 - statusFrequency: - type: integer - minimum: 0 - changeFrequency: - type: integer - minimum: 0 - deviceScanFrequency: - type: integer - minimum: 0 - bluetoothEnabled: - type: boolean - watchdogEnabled: - type: boolean - abstractedHardwareEnabled: - type: boolean - fogType: - type: integer - minimum: 0 - maximum: 2 - dockerPruningFrequency: - type: integer - minimum: 0 - availableDiskThreshold: - type: integer - minimum: 0 - logLevel: - type: string - isSystem: - type: boolean - routerMode: - enum: - - none - - edge - - interior - default: edge - messagingPort: - type: integer - minimum: 1 - maximum: 65535 - interRouterPort: - type: integer - minimum: 1 - maximum: 65535 - edgeRouterPort: - type: integer - minimum: 1 - maximum: 65535 - host: - type: string - tags: - type: array - items: - $ref: '#/components/schemas/iofogTag' - upstreamRouters: - type: array - items: - type: string - minLength: 1 - networkRouter: - type: string - timeZone: - type: string - anyOf: - - properties: - routerMode: {} - required: - - interRouterPort - - edgeRouterPort - - host - - properties: - routerMode: {} - required: - - host - - properties: - routerMode: {} - required: - - name - - fogType - iofogUpdate: - type: object - properties: - uuid: - type: string - name: - type: string - minLength: 1 - location: - type: string - latitude: - type: number - minimum: -90 - maximum: 90 - longitude: - type: number - minimum: -180 - maximum: 180 - description: - type: string - networkInterface: - type: string - dockerUrl: - type: string - containerEngine: - type: string - enum: - - docker - - podman - deploymentType: - type: string - enum: - - native - - container - diskLimit: - type: integer - minimum: 0 - diskDirectory: - type: string - memoryLimit: - type: integer - minimum: 0 - cpuLimit: - type: integer - minimum: 0 - logLimit: - type: integer - minimum: 0 - logDirectory: - type: string - logFileCount: - type: integer - minimum: 0 - statusFrequency: - type: integer - minimum: 0 - changeFrequency: - type: integer - minimum: 0 - deviceScanFrequency: - type: integer - minimum: 0 - bluetoothEnabled: - type: boolean - watchdogEnabled: - type: boolean - abstractedHardwareEnabled: - type: boolean - fogType: - type: integer - minimum: 0 - maximum: 2 - dockerPruningFrequency: - type: integer - minimum: 0 - availableDiskThreshold: - type: integer - minimum: 0 - logLevel: - type: string - isSystem: - type: boolean - routerMode: - enum: - - none - - edge - - interior - messagingPort: - type: integer - minimum: 1 - maximum: 65535 - interRouterPort: - type: integer - minimum: 1 - maximum: 65535 - edgeRouterPort: - type: integer - minimum: 1 - maximum: 65535 - host: - type: string - upstreamRouters: - type: array - items: - type: string - minLength: 1 - tags: - type: array - items: - $ref: '#/components/schemas/iofogTag' - networkRouter: - type: string - minLength: 1 - timeZone: - type: string - anyOf: - - properties: - routerMode: {} - required: - - interRouterPort - - edgeRouterPort - - host - - properties: - routerMode: {} - - properties: - routerMode: {} - required: - - uuid - iofogDelete: - type: object - properties: - uuid: - type: string - required: - - uuid - iofogGet: - type: object - properties: - uuid: - type: string - name: - type: string - oneOf: - - required: - - uuid - - required: - - name - iofogGenerateProvision: - type: object - properties: - uuid: - type: string - required: - - uuid - iofogSetVersionCommand: - type: object - properties: - uuid: - type: string - versionCommand: - enum: - - upgrade - - rollback - required: - - uuid - - versionCommand - iofogReboot: - type: object - properties: - uuid: - type: string - required: - - uuid - iofogFilters: - type: array - items: - $ref: '#/components/schemas/filter' - halGet: - type: object - properties: - uuid: - type: string - required: - - uuid - iofogPrune: - type: object - properties: - uuid: - type: string - required: - - uuid - defaultRouterCreate: - type: object - properties: - messagingPort: - type: integer - minimum: 1 - maximum: 65535 - interRouterPort: - type: integer - minimum: 1 - maximum: 65535 - edgeRouterPort: - type: integer - minimum: 1 - maximum: 65535 - requireSsl: - type: string - sslProfile: - type: string - saslMechanisms: - type: string - authenticatePeer: - type: string - caCert: - type: string - tlsCert: - type: string - tlsKey: - type: string - host: - type: string - required: - - host - microserviceCreate: - type: object - properties: - name: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - config: - type: string - annotations: - type: string - catalogItemId: - type: integer - minimum: 4 - images: - type: array - maxItems: 2 - items: - $ref: '#/components/schemas/image' - registryId: - type: integer - application: - anyOf: - - type: string - - type: number - iofogUuid: - type: string - agentName: - type: string - rootHostAccess: - type: boolean - schedule: - type: integer - minimum: 0 - maximum: 100 - logSize: - type: integer - imageSnapshot: - type: string - volumeMappings: - type: array - items: - $ref: '#/components/schemas/volumeMappings' - ports: - type: array - items: - $ref: '#/components/schemas/ports' - extraHosts: - type: array - items: - $ref: '#/components/schemas/extraHosts' - routes: - type: array - items: - type: string - env: - type: array - items: - $ref: '#/components/schemas/env' - cmd: - type: array - items: - type: string - cdiDevices: - type: array - items: - type: string - capAdd: - type: array - items: - type: string - capDrop: - type: array - items: - type: string - runAsUser: - type: string - platform: - type: string - runtime: - type: string - pubTags: - type: array - items: - type: string - subTags: - type: array - items: - type: string - required: - - name - microserviceUpdate: - type: object - properties: - name: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - config: - type: string - annotations: - type: string - rebuild: - type: boolean - iofogUuid: - type: string - agentName: - type: string - rootHostAccess: - type: boolean - logSize: - type: integer - minimum: 0 - schedule: - type: integer - minimum: 0 - maximum: 100 - volumeMappings: - type: array - items: - $ref: '#/components/schemas/volumeMappings' - images: - type: array - maxItems: 2 - minItems: 1 - items: - $ref: '#/components/schemas/image' - ports: - type: array - items: - $ref: '#/components/schemas/ports' - extraHosts: - type: array - items: - $ref: '#/components/schemas/extraHosts' - env: - type: array - items: - $ref: '#/components/schemas/env' - cmd: - type: array - items: - type: string - cdiDevices: - type: array - items: - type: string - capAdd: - type: array - items: - type: string - capDrop: - type: array - items: - type: string - runAsUser: - type: string - platform: - type: string - runtime: - type: string - pubTags: - type: array - items: - type: string - subTags: - type: array - items: - type: string - portsCreate: - type: object - properties: - internal: - type: integer - external: - type: integer - protocol: - enum: - - tcp - - udp - required: - - internal - - external - microserviceDelete: - type: object - properties: - withCleanup: - type: boolean - additionalProperties: - type: object - additionalProperties: true - registryCreate: - type: object - properties: - url: - type: string - minLength: 1 - isPublic: - type: boolean - username: - type: string - minLength: 1 - password: - type: string - email: - type: string - pattern: ^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$ - requiresCert: - type: boolean - certificate: - type: string - required: - - url - - isPublic - - username - - password - - email - registryDelete: - type: object - properties: - id: - type: integer - required: - - id - registryUpdate: - type: object - properties: - url: - type: string - minLength: 1 - isPublic: - type: boolean - username: - type: string - minLength: 1 - password: - type: string - email: - type: string - pattern: ^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$ - requiresCert: - type: boolean - certificate: - type: string - routingCreate: - type: object - properties: - name: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - oneOf: - - properties: - from: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - to: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - application: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - required: - - name - - from - - to - - properties: - sourceMicroserviceUuid: - type: string - destMicroserviceUuid: - type: string - required: - - name - - sourceMicroserviceUuid - - destMicroserviceUuid - routingUpdate: - type: object - properties: - name: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - oneOf: - - properties: - from: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - to: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - application: - type: string - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - required: - - from - - to - - application - - properties: - sourceMicroserviceUuid: - type: string - destMicroserviceUuid: - type: string - required: - - sourceMicroserviceUuid - - destMicroserviceUuid - secretCreate: - type: object - properties: - name: - type: string - minLength: 1 - maxLength: 255 - type: - type: string - enum: - - opaque - - tls - data: - type: object - required: - - name - - type - - data - secretUpdate: - type: object - properties: - data: - type: object - required: - - data - secretResponse: - type: object - properties: - id: - type: integer - name: - type: string - type: - type: string - enum: - - opaque - - tls - data: - type: object - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - id - - name - - type - - data - - created_at - - updated_at - secretListResponse: - type: object - properties: - secrets: - type: array - items: - type: object - properties: - id: - type: integer - name: - type: string - type: - type: string - enum: - - opaque - - tls - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - required: - - id - - name - - type - - created_at - - updated_at - required: - - secrets - serviceTag: - type: string - serviceCreate: - type: object - required: - - name - - type - - resource - - targetPort - properties: - name: - type: string - pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ - type: - type: string - enum: - - microservice - - k8s - - agent - - external - resource: - type: string - required: - - cpu - - memory - targetPort: - type: integer - defaultBridge: - type: string - servicePort: - type: integer - k8sType: - type: string - enum: - - LoadBalancer - - ClusterIP - - NodePort - tags: - type: array - items: - $ref: '#/components/schemas/serviceTag' - serviceUpdate: - type: object - required: - - name - properties: - name: - type: string - pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ - type: - type: string - enum: - - microservice - - k8s - - agent - - external - resource: - type: string - targetPort: - type: integer - defaultBridge: - type: string - servicePort: - type: integer - k8sType: - type: string - enum: - - LoadBalancer - - ClusterIP - - NodePort - tags: - type: array - items: - $ref: '#/components/schemas/serviceTag' - tunnelCreate: - type: object - properties: - iofogUuid: - type: string - username: - type: string - minLength: 1 - password: - type: string - rsakey: - type: string - lport: - type: integer - minimum: 0 - maximum: 65535 - rport: - type: integer - minimum: 0 - maximum: 65535 - required: - - iofogUuid - - username - - password - - lport - - rport - login: - type: object - properties: - email: - type: string - pattern: ^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$ - password: - type: string - totp: - type: string - required: - - email - - password - refresh: - type: object - properties: - refreshToken: - type: string - required: - - refreshToken - volumeMountCreate: - type: object - properties: - name: - type: string - pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ - secretName: - type: string - configMapName: - type: string - required: - - name - oneOf: - - required: - - secretName - - required: - - configMapName - volumeMountUpdate: - type: object - properties: - name: - type: string - pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ - secretName: - type: string - configMapName: - type: string - oneOf: - - required: - - secretName - - required: - - configMapName - volumeMountLink: - type: object - properties: - fogUuids: - type: array - items: - type: string - minItems: 1 - required: - - fogUuids - volumeMountUnlink: - type: object - properties: - fogUuids: - type: array - items: - type: string - minItems: 1 - required: - - fogUuids -security: - - authToken: [] -paths: - /agent/provision: - post: - tags: - - Agent - summary: POST /api/v3/agent/provision - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/agentProvision' - /agent/deprovision: - post: - tags: - - Agent - summary: POST /api/v3/agent/deprovision - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/agentProvision' - /agent/config: - get: - tags: - - Agent - summary: GET /api/v3/agent/config - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Agent - summary: PATCH /api/v3/agent/config - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /agent/config/changes: - get: - tags: - - Agent - summary: GET /api/v3/agent/config/changes - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Agent - summary: PATCH /api/v3/agent/config/changes - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /agent/status: - put: - tags: - - Agent - summary: PUT /api/v3/agent/status - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/updateAgentConfig' - /agent/edgeResources: - get: - tags: - - Agent - summary: GET /api/v3/agent/edgeResources - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/volumeMounts: - get: - tags: - - Agent - summary: GET /api/v3/agent/volumeMounts - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/microservices: - get: - tags: - - Agent - summary: GET /api/v3/agent/microservices - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/microservices/{microserviceUuid}: - get: - tags: - - Agent - summary: GET /api/v3/agent/microservices/:microserviceUuid - security: - - authToken: [] - parameters: - - name: microserviceUuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/registries: - get: - tags: - - Agent - summary: GET /api/v3/agent/registries - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/tunnel: - get: - tags: - - Agent - summary: GET /api/v3/agent/tunnel - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/strace: - get: - tags: - - Agent - summary: GET /api/v3/agent/strace - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - put: - tags: - - Agent - summary: PUT /api/v3/agent/strace - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/updateAgentConfig' - /agent/version: - get: - tags: - - Agent - summary: GET /api/v3/agent/version - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/hal/hw: - put: - tags: - - Agent - summary: PUT /api/v3/agent/hal/hw - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/updateAgentConfig' - /agent/hal/usb: - put: - tags: - - Agent - summary: PUT /api/v3/agent/hal/usb - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/updateAgentConfig' - /agent/delete-node: - delete: - tags: - - Agent - summary: DELETE /api/v3/agent/delete-node - security: - - authToken: [] - parameters: [] - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /agent/image-snapshot: - get: - tags: - - Agent - summary: GET /api/v3/agent/image-snapshot - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - put: - tags: - - Agent - summary: PUT /api/v3/agent/image-snapshot - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/updateAgentConfig' - /agent/cert: - get: - tags: - - Agent - summary: GET /api/v3/agent/cert - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /application: - get: - tags: - - Application - summary: GET /api/v3/application - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - applications: - type: array - items: - type: object - properties: - name: - type: string - description: - type: string - version: - type: string - microservices: - type: array - items: - type: object - properties: - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - post: - tags: - - Application - summary: POST /api/v3/application - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationCreate' - /application/system: - get: - tags: - - Application - summary: GET /api/v3/application/system - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - applications: - type: array - items: - type: object - properties: - name: - type: string - description: - type: string - version: - type: string - microservices: - type: array - items: - type: object - properties: - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /application/yaml: - post: - tags: - - Application - summary: POST /api/v3/application/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /application/{name}: - get: - tags: - - Application - summary: GET /api/v3/application/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - applications: - type: array - items: - type: object - properties: - name: - type: string - description: - type: string - version: - type: string - microservices: - type: array - items: - type: object - properties: - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Application - summary: PATCH /api/v3/application/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationPatch' - put: - tags: - - Application - summary: PUT /api/v3/application/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationUpdate' - delete: - tags: - - Application - summary: DELETE /api/v3/application/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /application/system/{name}: - get: - tags: - - Application - summary: GET /api/v3/application/system/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - applications: - type: array - items: - type: object - properties: - name: - type: string - description: - type: string - version: - type: string - microservices: - type: array - items: - type: object - properties: - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - delete: - tags: - - Application - summary: DELETE /api/v3/application/system/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /application/yaml/{name}: - put: - tags: - - Application - summary: PUT /api/v3/application/yaml/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationUpdate' - /applicationTemplates: - get: - tags: - - Application - summary: GET /api/v3/applicationTemplates - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - applications: - type: array - items: - type: object - properties: - name: - type: string - description: - type: string - version: - type: string - microservices: - type: array - items: - type: object - properties: - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /applicationTemplate: - post: - tags: - - Application - summary: POST /api/v3/applicationTemplate - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationCreate' - /applicationTemplate/yaml: - post: - tags: - - Application - summary: POST /api/v3/applicationTemplate/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /applicationTemplate/{name}: - get: - tags: - - Application - summary: GET /api/v3/applicationTemplate/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - applications: - type: array - items: - type: object - properties: - name: - type: string - description: - type: string - version: - type: string - microservices: - type: array - items: - type: object - properties: - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Application - summary: PATCH /api/v3/applicationTemplate/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationPatch' - put: - tags: - - Application - summary: PUT /api/v3/applicationTemplate/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationUpdate' - delete: - tags: - - Application - summary: DELETE /api/v3/applicationTemplate/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /applicationTemplate/yaml/{name}: - put: - tags: - - Application - summary: PUT /api/v3/applicationTemplate/yaml/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/applicationUpdate' - /capabilities/edgeResources: - head: - tags: - - Controller - summary: HEAD /api/v3/capabilities/edgeResources - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /capabilities/applicationTemplates: - head: - tags: - - Controller - summary: HEAD /api/v3/capabilities/applicationTemplates - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /catalog/microservices: - get: - tags: - - Catalog - summary: GET /api/v3/catalog/microservices - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - post: - tags: - - Catalog - summary: POST /api/v3/catalog/microservices - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - /catalog/microservices/{id}: - get: - tags: - - Catalog - summary: GET /api/v3/catalog/microservices/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Catalog - summary: PATCH /api/v3/catalog/microservices/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - delete: - tags: - - Catalog - summary: DELETE /api/v3/catalog/microservices/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /certificates/ca: - post: - tags: - - Certificates - summary: POST /api/v3/certificates/ca - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/certificateCreate' - get: - tags: - - Certificates - summary: GET /api/v3/certificates/ca - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /certificates/ca/{name}: - get: - tags: - - Certificates - summary: GET /api/v3/certificates/ca/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - delete: - tags: - - Certificates - summary: DELETE /api/v3/certificates/ca/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /certificates: - post: - tags: - - Certificates - summary: POST /api/v3/certificates - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/certificateCreate' - get: - tags: - - Certificates - summary: GET /api/v3/certificates - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /certificates/expiring: - get: - tags: - - Certificates - summary: GET /api/v3/certificates/expiring - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /certificates/{name}: - get: - tags: - - Certificates - summary: GET /api/v3/certificates/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - delete: - tags: - - Certificates - summary: DELETE /api/v3/certificates/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /certificates/{name}/renew: - post: - tags: - - Certificates - summary: POST /api/v3/certificates/:name/renew - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/certificateCreate' - /certificates/yaml: - post: - tags: - - Certificates - summary: POST /api/v3/certificates/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /config: - get: - tags: - - ConfigMap - summary: GET /api/v3/config - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - put: - tags: - - ConfigMap - summary: PUT /api/v3/config - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/configUpdate' - /config/{key}: - get: - tags: - - ConfigMap - summary: GET /api/v3/config/:key - security: - - authToken: [] - parameters: - - name: key - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /configmaps: - post: - tags: - - ConfigMap - summary: POST /api/v3/configmaps - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - get: - tags: - - ConfigMap - summary: GET /api/v3/configmaps - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /configmaps/yaml: - post: - tags: - - ConfigMap - summary: POST /api/v3/configmaps/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /configmaps/{name}: - patch: - tags: - - ConfigMap - summary: PATCH /api/v3/configmaps/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - get: - tags: - - ConfigMap - summary: GET /api/v3/configmaps/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - delete: - tags: - - ConfigMap - summary: DELETE /api/v3/configmaps/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /configmaps/yaml/{name}: - patch: - tags: - - ConfigMap - summary: PATCH /api/v3/configmaps/yaml/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /status: - get: - tags: - - Controller - summary: GET /api/v3/status - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /fog-types/: - get: - tags: - - Controller - summary: GET /api/v3/fog-types/ - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/{uuid}/image-snapshot: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/:uuid/image-snapshot - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - get: - tags: - - Microservices - summary: GET /api/v3/microservices/:uuid/image-snapshot - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/{uuid}/strace: - patch: - tags: - - Microservices - summary: PATCH /api/v3/microservices/:uuid/strace - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - get: - tags: - - Microservices - summary: GET /api/v3/microservices/:uuid/strace - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - put: - tags: - - Microservices - summary: PUT /api/v3/microservices/:uuid/strace - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceUpdate' - /edgeResources: - get: - tags: - - Edge Resource - summary: GET /api/v3/edgeResources - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /edgeResource/{name}/{version}: - get: - tags: - - Edge Resource - summary: GET /api/v3/edgeResource/:name/:version - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - - name: version - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - put: - tags: - - Edge Resource - summary: PUT /api/v3/edgeResource/:name/:version - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - - name: version - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/edgeResourceUpdate' - delete: - tags: - - Edge Resource - summary: DELETE /api/v3/edgeResource/:name/:version - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - - name: version - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /edgeResource/{name}: - get: - tags: - - Edge Resource - summary: GET /api/v3/edgeResource/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /edgeResource: - post: - tags: - - Edge Resource - summary: POST /api/v3/edgeResource - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/edgeResourceCreate' - /edgeResource/{name}/{version}/link: - post: - tags: - - Edge Resource - summary: POST /api/v3/edgeResource/:name/:version/link - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - - name: version - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/edgeResourceCreate' - delete: - tags: - - Edge Resource - summary: DELETE /api/v3/edgeResource/:name/:version/link - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - - name: version - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /flow: - get: - tags: - - Application - summary: GET /api/v3/flow - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - post: - tags: - - Application - summary: POST /api/v3/flow - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /flow/{id}: - get: - tags: - - Application - summary: GET /api/v3/flow/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Application - summary: PATCH /api/v3/flow/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - delete: - tags: - - Application - summary: DELETE /api/v3/flow/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /iofog-list: - get: - tags: - - ioFog - summary: GET /api/v3/iofog-list - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /iofog: - post: - tags: - - ioFog - summary: POST /api/v3/iofog - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/iofogCreate' - /iofog/{uuid}: - patch: - tags: - - ioFog - summary: PATCH /api/v3/iofog/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - delete: - tags: - - ioFog - summary: DELETE /api/v3/iofog/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - get: - tags: - - ioFog - summary: GET /api/v3/iofog/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /iofog/{uuid}/provisioning-key: - get: - tags: - - ioFog - summary: GET /api/v3/iofog/:uuid/provisioning-key - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /iofog/{uuid}/version/{versionCommand}: - post: - tags: - - ioFog - summary: POST /api/v3/iofog/:uuid/version/:versionCommand - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - - name: versionCommand - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/iofogCreate' - /iofog/{uuid}/reboot: - post: - tags: - - ioFog - summary: POST /api/v3/iofog/:uuid/reboot - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/iofogCreate' - /iofog/{uuid}/hal/hw: - get: - tags: - - ioFog - summary: GET /api/v3/iofog/:uuid/hal/hw - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /iofog/{uuid}/hal/usb: - get: - tags: - - ioFog - summary: GET /api/v3/iofog/:uuid/hal/usb - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /iofog/{uuid}/prune: - post: - tags: - - ioFog - summary: POST /api/v3/iofog/:uuid/prune - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/iofogCreate' - /microservices/: - get: - tags: - - Microservices - summary: GET /api/v3/microservices/ - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/system: - get: - tags: - - Microservices - summary: GET /api/v3/microservices/system - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices: - post: - tags: - - Microservices - summary: POST /api/v3/microservices - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - /microservices/yaml: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /microservices/{uuid}: - get: - tags: - - Microservices - summary: GET /api/v3/microservices/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Microservices - summary: PATCH /api/v3/microservices/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/system/{uuid}: - get: - tags: - - Microservices - summary: GET /api/v3/microservices/system/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Microservices - summary: PATCH /api/v3/microservices/system/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /microservices/pub/{tag}: - get: - tags: - - Microservices - summary: GET /api/v3/microservices/pub/:tag - security: - - authToken: [] - parameters: - - name: tag - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/sub/{tag}: - get: - tags: - - Microservices - summary: GET /api/v3/microservices/sub/:tag - security: - - authToken: [] - parameters: - - name: tag - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/{uuid}/rebuild: - patch: - tags: - - Microservices - summary: PATCH /api/v3/microservices/:uuid/rebuild - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /microservices/system/{uuid}/rebuild: - patch: - tags: - - Microservices - summary: PATCH /api/v3/microservices/system/:uuid/rebuild - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /microservices/yaml/{uuid}: - patch: - tags: - - Microservices - summary: PATCH /api/v3/microservices/yaml/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /microservices/system/yaml/{uuid}: - patch: - tags: - - Microservices - summary: PATCH /api/v3/microservices/system/yaml/:uuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /microservices/{uuid}/routes/{receiverUuid}: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/:uuid/routes/:receiverUuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - - name: receiverUuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/:uuid/routes/:receiverUuid - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - - name: receiverUuid - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/{uuid}/port-mapping: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/:uuid/port-mapping - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - get: - tags: - - Microservices - summary: GET /api/v3/microservices/:uuid/port-mapping - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/system/{uuid}/port-mapping: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/system/:uuid/port-mapping - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - /microservices/{uuid}/port-mapping/{internalPort}: - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/:uuid/port-mapping/:internalPort - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - - name: internalPort - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/system/{uuid}/port-mapping/{internalPort}: - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/system/:uuid/port-mapping/:internalPort - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - - name: internalPort - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/{uuid}/volume-mapping: - get: - tags: - - Microservices - summary: GET /api/v3/microservices/:uuid/volume-mapping - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - properties: - microservices: - type: array - items: - type: object - properties: - uuid: - type: string - name: - type: string - config: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - post: - tags: - - Microservices - summary: POST /api/v3/microservices/:uuid/volume-mapping - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - /microservices/system/{uuid}/volume-mapping: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/system/:uuid/volume-mapping - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - /microservices/{uuid}/volume-mapping/{id}: - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/:uuid/volume-mapping/:id - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/system/{uuid}/volume-mapping/{id}: - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/system/:uuid/volume-mapping/:id - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/{uuid}/exec: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/:uuid/exec - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/:uuid/exec - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /microservices/system/{uuid}/exec: - post: - tags: - - Microservices - summary: POST /api/v3/microservices/system/:uuid/exec - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/microserviceCreate' - delete: - tags: - - Microservices - summary: DELETE /api/v3/microservices/system/:uuid/exec - security: - - authToken: [] - parameters: - - name: uuid - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /registries: - post: - tags: - - Registries - summary: POST /api/v3/registries - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - get: - tags: - - Registries - summary: GET /api/v3/registries - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /registries/{id}: - delete: - tags: - - Registries - summary: DELETE /api/v3/registries/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Registries - summary: PATCH /api/v3/registries/:id - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /router: - get: - tags: - - Router - summary: GET /api/v3/router - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - put: - tags: - - Router - summary: PUT /api/v3/router - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /routes: - get: - tags: - - Routing - summary: GET /api/v3/routes - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - post: - tags: - - Routing - summary: POST /api/v3/routes - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /routes/{appName}/{name}: - get: - tags: - - Routing - summary: GET /api/v3/routes/:appName/:name - security: - - authToken: [] - parameters: - - name: appName - in: path - required: true - schema: - type: string - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Routing - summary: PATCH /api/v3/routes/:appName/:name - security: - - authToken: [] - parameters: - - name: appName - in: path - required: true - schema: - type: string - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - delete: - tags: - - Routing - summary: DELETE /api/v3/routes/:appName/:name - security: - - authToken: [] - parameters: - - name: appName - in: path - required: true - schema: - type: string - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /secrets: - post: - tags: - - Secrets - summary: POST /api/v3/secrets - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/secretCreate' - get: - tags: - - Secrets - summary: GET /api/v3/secrets - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /secrets/yaml: - post: - tags: - - Secrets - summary: POST /api/v3/secrets/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /secrets/{name}: - patch: - tags: - - Secrets - summary: PATCH /api/v3/secrets/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - get: - tags: - - Secrets - summary: GET /api/v3/secrets/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - delete: - tags: - - Secrets - summary: DELETE /api/v3/secrets/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /secrets/yaml/{name}: - patch: - tags: - - Secrets - summary: PATCH /api/v3/secrets/yaml/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /services: - get: - tags: - - Services - summary: GET /api/v3/services - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - post: - tags: - - Services - summary: POST /api/v3/services - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/serviceCreate' - /services/{name}: - get: - tags: - - Services - summary: GET /api/v3/services/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - Services - summary: PATCH /api/v3/services/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - delete: - tags: - - Services - summary: DELETE /api/v3/services/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /services/yaml: - post: - tags: - - Services - summary: POST /api/v3/services/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /services/yaml/{name}: - patch: - tags: - - Services - summary: PATCH /api/v3/services/yaml/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /iofog/{id}/tunnel: - patch: - tags: - - ioFog - summary: PATCH /api/v3/iofog/:id/tunnel - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - get: - tags: - - ioFog - summary: GET /api/v3/iofog/:id/tunnel - security: - - authToken: [] - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /user/login: - post: - tags: - - User - summary: POST /api/v3/user/login - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/login' - /user/refresh: - post: - tags: - - User - summary: POST /api/v3/user/refresh - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/login' - /user/profile: - get: - tags: - - User - summary: GET /api/v3/user/profile - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /user/logout: - post: - tags: - - User - summary: POST /api/v3/user/logout - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/login' - /volumeMounts: - get: - tags: - - VolumeMounts - summary: GET /api/v3/volumeMounts - security: - - authToken: [] - parameters: [] - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - post: - tags: - - VolumeMounts - summary: POST /api/v3/volumeMounts - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/volumeMountCreate' - /volumeMounts/{name}: - get: - tags: - - VolumeMounts - summary: GET /api/v3/volumeMounts/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - patch: - tags: - - VolumeMounts - summary: PATCH /api/v3/volumeMounts/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - delete: - tags: - - VolumeMounts - summary: DELETE /api/v3/volumeMounts/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - /volumeMounts/yaml: - post: - tags: - - VolumeMounts - summary: POST /api/v3/volumeMounts/yaml - security: - - authToken: [] - parameters: [] - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - application: - type: string - format: binary - /volumeMounts/yaml/{name}: - patch: - tags: - - VolumeMounts - summary: PATCH /api/v3/volumeMounts/yaml/:name - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - type: object - /volumeMounts/{name}/link: - post: - tags: - - VolumeMounts - summary: POST /api/v3/volumeMounts/:name/link - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '201': - description: Created - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - content: - application/json: - schema: - type: object - '400': - description: Bad Request - '401': - description: Not Authorized - '409': - description: Duplicate Name - '500': - description: Internal Server Error - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/volumeMountCreate' - delete: - tags: - - VolumeMounts - summary: DELETE /api/v3/volumeMounts/:name/link - security: - - authToken: [] - parameters: - - name: name - in: path - required: true - schema: - type: string - responses: - '204': - description: Success - headers: - X-Timestamp: - description: FogController server timestamp - schema: - type: number - '401': - description: Not Authorized - '404': - description: Not Found - '500': - description: Internal Server Error diff --git a/docs/swagger.yaml b/docs/swagger.yaml index c7b83042..f38adde9 100755 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -5165,7 +5165,9 @@ components: type: string iofogUuid: type: string - rootHostAccess: + hostNetworkMode: + type: boolean + isPrivileged: type: boolean logSize: type: number @@ -5316,7 +5318,9 @@ components: type: string agentName: type: string - rootHostAccess: + hostNetworkMode: + type: boolean + isPrivileged: type: boolean logSize: type: number @@ -6012,7 +6016,9 @@ components: type: string rebuild: type: boolean - rootHostAccess: + hostNetworkMode: + type: boolean + isPrivileged: type: boolean logSize: type: number @@ -6204,12 +6210,6 @@ components: type: string isPublic: type: boolean - isSecure: - type: boolean - certificate: - type: string - requiresCert: - type: boolean username: type: string password: @@ -6229,10 +6229,6 @@ components: type: string email: type: string - requiresCert: - type: boolean - certificate: - type: string ActionBody: type: object properties: @@ -6374,7 +6370,9 @@ components: type: string annotations: type: string - rootHostAccess: + hostNetworkMode: + type: boolean + isPrivileged: type: boolean logLimit: type: number @@ -6467,7 +6465,9 @@ components: type: string agentName: type: string - rootHostAccess: + hostNetworkMode: + type: boolean + isPrivileged: type: boolean logSize: type: number @@ -6526,7 +6526,9 @@ components: type: string agentName: type: string - rootHostAccess: + hostNetworkMode: + type: boolean + isPrivileged: type: boolean logLimit: type: number diff --git a/generate-swagger.sh b/generate-swagger.sh index 3b458750..cf964e82 100755 --- a/generate-swagger.sh +++ b/generate-swagger.sh @@ -1,2 +1,2 @@ #!/bin/bash -node scripts/generate-swagger.js \ No newline at end of file +docker run -v ./docs:/docs mitjaziv/swagger-codegen-cli generate -i /docs/swagger.yaml -l swagger -o /docs \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0ab344b8..1c0c914e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@datasance/iofogcontroller", - "version": "3.5.6", + "version": "3.5.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@datasance/iofogcontroller", - "version": "3.5.6", + "version": "3.5.7", "hasInstallScript": true, "license": "EPL-2.0", "dependencies": { - "@datasance/ecn-viewer": "1.2.1", + "@datasance/ecn-viewer": "1.2.2", "@kubernetes/client-node": "^0.22.3", "@msgpack/msgpack": "^3.1.2", "@opentelemetry/api": "^1.9.0", @@ -55,12 +55,12 @@ "os": "0.1.2", "path": "0.12.7", "pg": "8.12.0", - "pino": "9.1.0", + "pino": "9.13.1", "pino-std-serializers": "7.0.0", "portscanner": "2.2.0", "qs": "6.12.1", "retry-as-promised": "7.0.4", - "sequelize": "6.37.3", + "sequelize": "6.37.7", "sqlite3": "^5.1.7", "string-format": "2.0.0", "umzug": "^3.7.0", @@ -426,9 +426,9 @@ } }, "node_modules/@datasance/ecn-viewer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@datasance/ecn-viewer/-/ecn-viewer-1.2.1.tgz", - "integrity": "sha512-l7st68cRAJIHfKQq3NOY6kV5dCU6kTHS/CnZCnxnC2i4GJcjVgWNgCo9IdS+gLkgVPL9Xh68VnndW/fYyd057Q==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@datasance/ecn-viewer/-/ecn-viewer-1.2.2.tgz", + "integrity": "sha512-IpDHtj90jg6AvEsZ3oj+y1K3FkJHem7HoIjQE+Tce4LE9Sk/hqgUsI5gW+VgjmWUIyME9W3Nw86S4AYx0uINEw==" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", @@ -2422,17 +2422,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -5466,22 +5455,6 @@ "es5-ext": "~0.10.14" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, "node_modules/eventuate": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eventuate/-/eventuate-4.0.0.tgz", @@ -5829,14 +5802,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/fast-redact": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", - "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", - "engines": { - "node": ">=6" - } - }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", @@ -10582,19 +10547,19 @@ } }, "node_modules/pino": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-9.1.0.tgz", - "integrity": "sha512-qUcgfrlyOtjwhNLdbhoL7NR4NkHjzykAPw0V2QLFbvu/zss29h4NkRnibyFzBrNCbzCOY3WZ9hhKSwfOkNggYA==", + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.13.1.tgz", + "integrity": "sha512-Szuj+ViDTjKPQYiKumGmEn3frdl+ZPSdosHyt9SnUevFosOkMY2b7ipxlEctNKPmMD/VibeBI+ZcZCJK+4DPuw==", "dependencies": { "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.2.0", + "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", - "process-warning": "^3.0.0", + "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", + "slow-redact": "^0.3.0", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, @@ -10603,60 +10568,13 @@ } }, "node_modules/pino-abstract-transport": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", - "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", "dependencies": { - "readable-stream": "^4.0.0", "split2": "^4.0.0" } }, - "node_modules/pino-abstract-transport/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-abstract-transport/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/pino-std-serializers": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", @@ -11240,9 +11158,19 @@ } }, "node_modules/process-warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", - "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] }, "node_modules/progress": { "version": "2.0.3", @@ -12208,9 +12136,9 @@ "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" }, "node_modules/sequelize": { - "version": "6.37.3", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.3.tgz", - "integrity": "sha512-V2FTqYpdZjPy3VQrZvjTPnOoLm0KudCRXfGWp48QwhyPPp2yW8z0p0sCYZd/em847Tl2dVxJJ1DR+hF+O77T7A==", + "version": "6.37.7", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.7.tgz", + "integrity": "sha512-mCnh83zuz7kQxxJirtFD7q6Huy6liPanI67BSlbzSYgVNl5eXVdE2CN1FuAeZwG1SNpGsNRCV+bJAVVnykZAFA==", "funding": [ { "type": "opencollective", @@ -12698,6 +12626,11 @@ "node": ">=4" } }, + "node_modules/slow-redact": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/slow-redact/-/slow-redact-0.3.1.tgz", + "integrity": "sha512-NvFvl1GuLZNW4U046Tfi8b26zXo8aBzgCAS2f7yVJR/fArN93mOqSA99cB9uITm92ajSz01bsu1K7SCVVjIMpQ==" + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -14066,9 +13999,9 @@ } }, "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -14717,9 +14650,9 @@ } }, "node_modules/validator": { - "version": "13.15.15", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", - "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", + "version": "13.15.20", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.20.tgz", + "integrity": "sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==", "engines": { "node": ">= 0.10" } diff --git a/package.json b/package.json index c84a8064..9f981962 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@datasance/iofogcontroller", - "version": "3.5.6", + "version": "3.5.7", "description": "ioFog Controller project for Datasance PoT @ datasance.com \\nCopyright (c) 2023 Datasance Teknoloji A.S.", "main": "./src/main.js", "author": "Emirhan Durmus", @@ -55,7 +55,7 @@ "iofog-controller": "src/main.js" }, "dependencies": { - "@datasance/ecn-viewer": "1.2.1", + "@datasance/ecn-viewer": "1.2.2", "@kubernetes/client-node": "^0.22.3", "@msgpack/msgpack": "^3.1.2", "@opentelemetry/api": "^1.9.0", @@ -100,12 +100,12 @@ "os": "0.1.2", "path": "0.12.7", "pg": "8.12.0", - "pino": "9.1.0", + "pino": "9.13.1", "pino-std-serializers": "7.0.0", "portscanner": "2.2.0", "qs": "6.12.1", "retry-as-promised": "7.0.4", - "sequelize": "6.37.3", + "sequelize": "6.37.7", "sqlite3": "^5.1.7", "string-format": "2.0.0", "umzug": "^3.7.0", @@ -150,8 +150,11 @@ }, "sqlite3": { "prebuild-install": { - "tar-fs": "^2.1.3" + "tar-fs": "^2.1.4" } + }, + "sequelize": { + "validator": "^13.15.20" } } } diff --git a/scripts/generate-swagger.js b/scripts/generate-swagger.js deleted file mode 100644 index e04a61ee..00000000 --- a/scripts/generate-swagger.js +++ /dev/null @@ -1,778 +0,0 @@ -const fs = require('fs') -const path = require('path') -const yaml = require('js-yaml') - -// Base Swagger configuration -const swaggerBase = { - openapi: '3.0.0', - info: { - title: 'Datasance PoT Controller', - version: '3.5.0', - description: 'Datasance PoT Controller REST API Documentation' - }, - servers: [ - { - url: 'http://localhost:51121/api/v3' - } - ], - tags: [ - { name: 'Controller', description: 'Manage your controller' }, - { name: 'ioFog', description: 'Manage your agents' }, - { name: 'Application', description: 'Manage your applications' }, - { name: 'Application Template', description: 'Manage your application templates' }, - { name: 'Catalog', description: 'Manage your catalog' }, - { name: 'Registries', description: 'Manage your registries' }, - { name: 'Microservices', description: 'Manage your microservices' }, - { name: 'Routing', description: 'Manage your routes' }, - { name: 'Router', description: 'Manage your Default Router' }, - { name: 'Edge Resource', description: 'Manage your Edge Resources' }, - { name: 'Diagnostics', description: 'Diagnostic your microservices' }, - { name: 'Tunnel', description: 'Manage ssh tunnels' }, - { name: 'Agent', description: 'Used by your agents to communicate with your controller' }, - { name: 'User', description: 'Manage your users' }, - { name: 'Secrets', description: 'Manage your secrets' }, - { name: 'Certificates', description: 'Manage your certificates' }, - { name: 'Services', description: 'Manage your services' }, - { name: 'VolumeMounts', description: 'Manage your volume mounts' }, - { name: 'ConfigMap', description: 'Manage your config maps' } - ], - components: { - securitySchemes: { - authToken: { - type: 'http', - scheme: 'bearer', - bearerFormat: 'JWT', - description: 'JWT token for authentication (user or agent)' - } - }, - schemas: {} - }, - security: [ - { - authToken: [] - } - ], - paths: {} -} - -// Common response headers -const commonHeaders = { - 'X-Timestamp': { - description: 'FogController server timestamp', - schema: { - type: 'number' - } - } -} - -// Map HTTP methods to response schemas -const responseSchemas = { - get: { - '200': { - description: 'Success', - headers: commonHeaders, - content: { - 'application/json': { - schema: { - type: 'object' - } - } - } - }, - '401': { - description: 'Not Authorized' - }, - '404': { - description: 'Not Found' - }, - '500': { - description: 'Internal Server Error' - } - }, - post: { - '201': { - description: 'Created', - headers: commonHeaders, - content: { - 'application/json': { - schema: { - type: 'object' - } - } - } - }, - '400': { - description: 'Bad Request' - }, - '401': { - description: 'Not Authorized' - }, - '409': { - description: 'Duplicate Name' - }, - '500': { - description: 'Internal Server Error' - } - }, - put: { - '200': { - description: 'Success', - headers: commonHeaders, - content: { - 'application/json': { - schema: { - type: 'object' - } - } - } - }, - '400': { - description: 'Bad Request' - }, - '401': { - description: 'Not Authorized' - }, - '404': { - description: 'Not Found' - }, - '500': { - description: 'Internal Server Error' - } - }, - delete: { - '204': { - description: 'Success', - headers: commonHeaders - }, - '401': { - description: 'Not Authorized' - }, - '404': { - description: 'Not Found' - }, - '500': { - description: 'Internal Server Error' - } - } -} - -// Convert JSON Schema to OpenAPI Schema -function convertJsonSchemaToOpenAPI (schema) { - if (!schema) return {} - const openAPISchema = { ...schema } - - // Remove JSON Schema specific properties - delete openAPISchema.id - delete openAPISchema.$schema - - // Remove OpenAPI-incompatible properties - delete openAPISchema.if - delete openAPISchema.then - delete openAPISchema.const - delete openAPISchema.optional - - // Handle required arrays - if (openAPISchema.required && Array.isArray(openAPISchema.required) && openAPISchema.required.length === 0) { - delete openAPISchema.required - } - - // Convert $ref to OpenAPI format - if (openAPISchema.$ref) { - const refPath = openAPISchema.$ref.replace(/^\//, '') - // Only add #/components/schemas/ if it's not already there - if (!refPath.startsWith('#/components/schemas/')) { - openAPISchema.$ref = `#/components/schemas/${refPath}` - } else { - openAPISchema.$ref = refPath - } - } - - // Handle properties - if (openAPISchema.properties) { - Object.keys(openAPISchema.properties).forEach(key => { - if (openAPISchema.properties[key].$ref) { - const refPath = openAPISchema.properties[key].$ref.replace(/^\//, '') - // Only add #/components/schemas/ if it's not already there - if (!refPath.startsWith('#/components/schemas/')) { - openAPISchema.properties[key].$ref = `#/components/schemas/${refPath}` - } else { - openAPISchema.properties[key].$ref = refPath - } - } - // Remove additional properties from nested objects - if (openAPISchema.properties[key].type === 'object') { - delete openAPISchema.properties[key].additionalProperties - } - // Handle items in arrays - if (openAPISchema.properties[key].items) { - if (openAPISchema.properties[key].items.type === 'object') { - delete openAPISchema.properties[key].items.additionalProperties - // Convert key/value pairs to properties - if (openAPISchema.properties[key].items.key && openAPISchema.properties[key].items.value) { - openAPISchema.properties[key].items = { - type: 'object', - properties: { - key: openAPISchema.properties[key].items.key, - value: openAPISchema.properties[key].items.value - } - } - } - } - // Handle array item references - if (openAPISchema.properties[key].items.$ref) { - const refPath = openAPISchema.properties[key].items.$ref.replace(/^\//, '') - // Only add #/components/schemas/ if it's not already there - if (!refPath.startsWith('#/components/schemas/')) { - openAPISchema.properties[key].items = { - $ref: `#/components/schemas/${refPath}` - } - } else { - openAPISchema.properties[key].items = { - $ref: refPath - } - } - } - } - // Handle required arrays in properties - if (openAPISchema.properties[key].required && Array.isArray(openAPISchema.properties[key].required)) { - if (openAPISchema.properties[key].required.length === 0) { - delete openAPISchema.properties[key].required - } - } - // Handle intermediateCert optional property - if (key === 'intermediateCert') { - delete openAPISchema.properties[key].optional - } - // Handle microserviceDelete additionalProperties - if (key === 'additionalProperties') { - openAPISchema.properties[key] = { - type: 'object', - additionalProperties: true - } - } - // Handle serviceCreate resource required - if (key === 'resource' && openAPISchema.properties[key].required) { - if (!Array.isArray(openAPISchema.properties[key].required)) { - openAPISchema.properties[key].required = ['cpu', 'memory'] - } - } - }) - } - - // Handle array items - if (openAPISchema.items) { - if (openAPISchema.items.$ref) { - const refPath = openAPISchema.items.$ref.replace(/^\//, '') - // Only add #/components/schemas/ if it's not already there - if (!refPath.startsWith('#/components/schemas/')) { - openAPISchema.items.$ref = `#/components/schemas/${refPath}` - } else { - openAPISchema.items.$ref = refPath - } - } - // Remove additional properties from array items - if (openAPISchema.items.type === 'object') { - delete openAPISchema.items.additionalProperties - } - } - - // Handle allOf/anyOf - if (openAPISchema.allOf) { - openAPISchema.allOf = openAPISchema.allOf.map(item => { - const converted = convertJsonSchemaToOpenAPI(item) - // Remove const from routerMode in anyOf/allOf - if (converted.properties && converted.properties.routerMode) { - delete converted.properties.routerMode.const - } - return converted - }) - } - if (openAPISchema.anyOf) { - openAPISchema.anyOf = openAPISchema.anyOf.map(item => { - const converted = convertJsonSchemaToOpenAPI(item) - // Remove const from routerMode in anyOf/allOf - if (converted.properties && converted.properties.routerMode) { - delete converted.properties.routerMode.const - } - return converted - }) - } - - // Remove additionalProperties at root level - delete openAPISchema.additionalProperties - - return openAPISchema -} - -// Convert path parameters from :param to {param} format and remove /api/v3 prefix -function convertPathParameters (path) { - // Remove /api/v3 prefix if present - const pathWithoutPrefix = path.replace(/^\/api\/v3/, '') - // Convert :param to {param} - return pathWithoutPrefix.replace(/:([^/]+)/g, '{$1}') -} - -// Get response schema based on route path and method -function getResponseSchema (path, method) { - const baseResponse = JSON.parse(JSON.stringify(responseSchemas[method] || responseSchemas.get)) - // Customize response schema based on path - if (path.includes('/application')) { - if (method === 'get') { - baseResponse['200'].content['application/json'].schema = { - type: 'object', - properties: { - applications: { - type: 'array', - items: { - type: 'object', - properties: { - name: { type: 'string' }, - description: { type: 'string' }, - version: { type: 'string' }, - microservices: { - type: 'array', - items: { - type: 'object', - properties: { - name: { type: 'string' }, - config: { type: 'object' } - } - } - } - } - } - } - } - } - } - } else if (path.includes('/microservices')) { - if (method === 'get') { - baseResponse['200'].content['application/json'].schema = { - type: 'object', - properties: { - microservices: { - type: 'array', - items: { - type: 'object', - properties: { - uuid: { type: 'string' }, - name: { type: 'string' }, - config: { type: 'object' } - } - } - } - } - } - } - } - return baseResponse -} - -// Get request body schema based on route path and method -function getRequestBodySchema (path, method) { - // Handle YAML file upload endpoints - if (path.endsWith('/yaml')) { - return { - required: true, - content: { - 'multipart/form-data': { - schema: { - type: 'object', - properties: { - application: { - type: 'string', - format: 'binary' - } - } - } - } - } - } - } - - // Map routes to their corresponding schemas based on service validations - const schemaMapping = { - // Application routes - '/application': { - post: 'applicationCreate', - put: 'applicationUpdate', - patch: 'applicationPatch' - }, - // Microservice routes - '/microservices': { - post: 'microserviceCreate', - put: 'microserviceUpdate' - }, - // Iofog routes - '/iofog': { - post: 'iofogCreate', - put: 'iofogUpdate' - }, - // Agent routes - '/agent': { - post: 'agentProvision', - put: 'updateAgentConfig' - }, - // Routing routes - '/routing': { - post: 'routingCreate', - put: 'routingUpdate' - }, - // Secret routes - '/secret': { - post: 'secretCreate', - put: 'secretUpdate' - }, - // Service routes - '/service': { - post: 'serviceCreate', - put: 'serviceUpdate' - }, - // Certificate routes - '/certificate': { - post: 'certificateCreate', - put: 'caCreate' - }, - // Config map routes - '/configMap': { - post: 'configMapCreate', - put: 'configMapUpdate' - }, - // Volume mount routes - '/volumeMount': { - post: 'volumeMountCreate', - put: 'volumeMountUpdate' - }, - // Edge resource routes - '/edgeResource': { - post: 'edgeResourceCreate', - put: 'edgeResourceUpdate' - }, - // Application template routes - '/applicationTemplate': { - post: 'applicationTemplateCreate', - put: 'applicationTemplateUpdate', - patch: 'applicationTemplatePatch' - }, - // User routes - '/user': { - post: 'login', - put: 'refresh' - }, - // Catalog routes - '/catalog': { - post: 'catalogItemCreate', - put: 'catalogItemUpdate' - }, - // Registry routes - '/registry': { - post: 'registryCreate', - put: 'registryUpdate' - }, - // Tunnel routes - '/tunnel': { - post: 'tunnelCreate' - }, - // Config routes - '/config': { - put: 'configUpdate' - } - } - - // Find the matching schema for this path and method - for (const [routePath, methods] of Object.entries(schemaMapping)) { - if (path.includes(routePath) && methods[method]) { - const schemaName = methods[method] - return { - required: true, - content: { - 'application/json': { - schema: { - $ref: `#/components/schemas/${schemaName}` - } - } - } - } - } - } - - // Default JSON request body - return { - required: true, - content: { - 'application/json': { - schema: { - type: 'object' - } - } - } - } -} - -// Find the most similar tag from the tag list -function findMostSimilarTag (path) { - const pathSegments = path.split('/').filter(Boolean) - if (pathSegments.length === 0) return 'Controller' - - // Get the first meaningful segment (skip empty strings) - const firstSegment = pathSegments[0] - - // Define tag mapping for common paths - const tagMapping = { - 'application': 'Application', - 'applications': 'Application', - 'flow': 'Application', - 'flows': 'Application', - 'template': 'Application Template', - 'templates': 'Application Template', - 'catalog': 'Catalog', - 'registry': 'Registries', - 'registries': 'Registries', - 'microservice': 'Microservices', - 'microservices': 'Microservices', - 'route': 'Routing', - 'routes': 'Routing', - 'routing': 'Routing', - 'router': 'Router', - 'edgeResource': 'Edge Resource', - 'edgeResources': 'Edge Resource', - 'edge-resource': 'Edge Resource', - 'edge-resources': 'Edge Resource', - 'edge_resource': 'Edge Resource', - 'edge_resources': 'Edge Resource', - 'diagnostic': 'Diagnostics', - 'diagnostics': 'Diagnostics', - 'tunnel': 'Tunnel', - 'tunnels': 'Tunnel', - 'agent': 'Agent', - 'agents': 'Agent', - 'user': 'User', - 'users': 'User', - 'secret': 'Secrets', - 'secrets': 'Secrets', - 'certificate': 'Certificates', - 'certificates': 'Certificates', - 'service': 'Services', - 'services': 'Services', - 'volume': 'VolumeMounts', - 'volumes': 'VolumeMounts', - 'config': 'ConfigMap', - 'configs': 'ConfigMap', - 'iofog': 'ioFog' - } - - // Try to find an exact match first (case-insensitive) - const lowerFirstSegment = firstSegment.toLowerCase() - if (tagMapping[lowerFirstSegment]) { - return tagMapping[lowerFirstSegment] - } - - // Try to find a match with different case formats - const possibleFormats = [ - firstSegment, - firstSegment.toLowerCase(), - firstSegment.toUpperCase(), - firstSegment.replace(/([A-Z])/g, '-$1').toLowerCase(), - firstSegment.replace(/([A-Z])/g, '_$1').toLowerCase(), - firstSegment.charAt(0).toUpperCase() + firstSegment.slice(1) - ] - - for (const format of possibleFormats) { - if (tagMapping[format]) { - return tagMapping[format] - } - } - - // If no exact match, try to find the most similar tag - const tagNames = swaggerBase.tags.map(tag => tag.name.toLowerCase()) - let bestMatch = 'Controller' - let bestScore = 0 - - for (const tagName of tagNames) { - // Check if the path segment contains the tag name or vice versa - if (lowerFirstSegment.includes(tagName) || tagName.includes(lowerFirstSegment)) { - const score = Math.min(lowerFirstSegment.length, tagName.length) - if (score > bestScore) { - bestScore = score - bestMatch = swaggerBase.tags.find(tag => tag.name.toLowerCase() === tagName).name - } - } - } - - return bestMatch -} - -// Process route file -function processRouteFile (filePath) { - const routeFile = require(filePath) - const paths = {} - routeFile.forEach(route => { - // Skip WebSocket endpoints - if (route.method.toLowerCase() === 'ws') { - return - } - - const originalPath = route.path - const path = convertPathParameters(originalPath) - const method = route.method.toLowerCase() - if (!paths[path]) { - paths[path] = {} - } - // Extract parameters from path - const pathParams = [] - const pathRegex = /{([^}]+)}/g - let match - while ((match = pathRegex.exec(path)) !== null) { - pathParams.push({ - name: match[1], - in: 'path', - required: true, - schema: { - type: 'string' - } - }) - } - // Create path object - paths[path][method] = { - tags: [findMostSimilarTag(path)], - summary: `${method.toUpperCase()} ${originalPath}`, - security: [{ authToken: [] }], - parameters: pathParams, - responses: getResponseSchema(path, method) - } - // Add request body for POST/PUT/PATCH - if (['post', 'put', 'patch'].includes(method)) { - paths[path][method].requestBody = getRequestBodySchema(path, method) - } - }) - return paths -} - -// Process schema file -function processSchemaFile (filePath) { - const schemaFile = require(filePath) - const schemas = {} - - // Process all inner schemas first - if (schemaFile.innerSchemas) { - schemaFile.innerSchemas.forEach(schema => { - if (schema.id) { - const schemaName = schema.id.replace(/^\//, '') - schemas[schemaName] = convertJsonSchemaToOpenAPI(schema) - } - }) - } - - // Then process main schemas - if (schemaFile.mainSchemas) { - schemaFile.mainSchemas.forEach(schema => { - if (schema.id) { - const schemaName = schema.id.replace(/^\//, '') - schemas[schemaName] = convertJsonSchemaToOpenAPI(schema) - } - }) - } - - // Handle direct schema exports - Object.keys(schemaFile).forEach(key => { - if (typeof schemaFile[key] === 'object' && schemaFile[key].type) { - const schemaName = key - schemas[schemaName] = convertJsonSchemaToOpenAPI(schemaFile[key]) - } - }) - - return schemas -} - -// Main function -function generateSwagger () { - const routesDir = path.join(__dirname, '../src/routes') - const schemasDir = path.join(__dirname, '../src/schemas') - - // First, add base schemas that are commonly referenced - const baseSchemas = { - image: { - type: 'object', - properties: { - name: { type: 'string' }, - registry: { type: 'string' } - }, - required: ['name'] - }, - volumeMappings: { - type: 'object', - properties: { - hostDestination: { type: 'string' }, - containerDestination: { type: 'string' }, - accessMode: { type: 'string' }, - type: { type: 'string', enum: ['volume', 'bind'] } - }, - required: ['hostDestination', 'containerDestination', 'accessMode'] - }, - ports: { - type: 'object', - properties: { - internal: { type: 'integer' }, - external: { type: 'integer' }, - protocol: { type: 'string', enum: ['tcp', 'udp'] } - }, - required: ['internal', 'external'] - }, - extraHosts: { - type: 'object', - properties: { - name: { type: 'string' }, - address: { type: 'string' } - }, - required: ['name', 'address'] - }, - env: { - type: 'object', - properties: { - key: { type: 'string' }, - value: { type: 'string' }, - valueFromSecret: { type: 'string' }, - valueFromConfigMap: { type: 'string' } - }, - required: ['key'], - oneOf: [ - { required: ['value'] }, - { required: ['valueFromSecret'] }, - { required: ['valueFromConfigMap'] } - ] - } - } - - // Initialize schemas with base schemas - const allSchemas = { ...baseSchemas } - - // Process all schema files - fs.readdirSync(schemasDir) - .filter(file => file.endsWith('.js')) - .forEach(file => { - const schemaDefinitions = processSchemaFile(path.join(schemasDir, file)) - Object.assign(allSchemas, schemaDefinitions) - }) - - // Add all schemas to the OpenAPI document - swaggerBase.components.schemas = allSchemas - - // Process all route files - fs.readdirSync(routesDir) - .filter(file => file.endsWith('.js')) - .forEach(file => { - const routePaths = processRouteFile(path.join(routesDir, file)) - Object.assign(swaggerBase.paths, routePaths) - }) - - // Write to YAML file - const yamlStr = yaml.dump(swaggerBase, { - noRefs: true, // Disable YAML anchors and references - lineWidth: -1, // Disable line wrapping - noCompatMode: true // Use modern YAML features - }) - fs.writeFileSync(path.join(__dirname, '../docs/swagger-test.yaml'), yamlStr) - console.log('Swagger YAML generated successfully!') -} - -generateSwagger() diff --git a/src/cli/microservice.js b/src/cli/microservice.js index e105537e..589b0cde 100644 --- a/src/cli/microservice.js +++ b/src/cli/microservice.js @@ -35,7 +35,8 @@ const JSON_SCHEMA_ADD = AppHelper.stringifyCliJsonSchema( registryId: 1, application: 'string', iofogUuid: 'string', - rootHostAccess: true, + hostNetworkMode: true, + isPrivileged: true, logSize: 0, volumeMappings: [ { @@ -86,7 +87,8 @@ const JSON_SCHEMA_UPDATE = AppHelper.stringifyCliJsonSchema( annotations: 'string', rebuild: true, iofogUuid: 'string', - rootHostAccess: true, + hostNetworkMode: true, + isPrivileged: true, logSize: 0, catalogItemId: 0, images: [ @@ -234,17 +236,17 @@ class Microservice extends BaseCLIHandler { group: [constants.CMD_UPDATE, constants.CMD_ADD] }, { - name: 'root-enable', - alias: 'r', + name: 'host-network-mode', + alias: 'hN', type: Boolean, - description: 'Enable root access', + description: 'Enable host network mode', group: [constants.CMD_UPDATE, constants.CMD_ADD] }, { - name: 'root-disable', - alias: 'R', + name: 'is-privileged', + alias: 'iP', type: Boolean, - description: 'Disable root access', + description: 'Enable privileged mode', group: [constants.CMD_UPDATE, constants.CMD_ADD] }, { @@ -663,7 +665,8 @@ const _updateMicroserviceObject = function (obj) { config: obj.config, annotations: obj.annotations, iofogUuid: obj.iofogUuid, - rootHostAccess: AppHelper.validateBooleanCliOptions(obj.rootEnable, obj.rootDisable), + hostNetworkMode: obj.hostNetworkMode, + isPrivileged: obj.isPrivileged, logSize: (obj.logSize || constants.MICROSERVICE_DEFAULT_LOG_SIZE) * 1, rebuild: obj.rebuild, cmd: obj.cmd, @@ -731,7 +734,8 @@ const _createMicroserviceObject = function (obj) { application: obj.applicationName, registryId: parseInt(obj.registryId) || undefined, iofogUuid: obj.iofogUuid, - rootHostAccess: AppHelper.validateBooleanCliOptions(obj.rootEnable, obj.rootDisable), + hostNetworkMode: obj.hostNetworkMode, + isPrivileged: obj.isPrivileged, logSize: (obj.logSize || constants.MICROSERVICE_DEFAULT_LOG_SIZE) * 1, routes: obj.routes, cmd: obj.cmd, diff --git a/src/cli/registry.js b/src/cli/registry.js index 046bdbc1..1efee349 100644 --- a/src/cli/registry.js +++ b/src/cli/registry.js @@ -64,20 +64,6 @@ class Registry extends BaseCLIHandler { description: 'Password', group: [constants.CMD_ADD, constants.CMD_UPDATE] }, - { - name: 'requires-certificate', - alias: 'c', - type: Boolean, - description: 'Requires certificate', - group: [constants.CMD_ADD, constants.CMD_UPDATE] - }, - { - name: 'certificate', - alias: 'C', - type: String, - description: 'Certificate', - group: [constants.CMD_ADD, constants.CMD_UPDATE] - }, { name: 'email', alias: 'e', @@ -183,9 +169,7 @@ function _createRegistryObject (cliData) { username: cliData.username, password: cliData.password, isPublic: AppHelper.validateBooleanCliOptions(cliData.public, cliData.private), - email: cliData.email, - requiresCert: cliData.requiresCertificate, - certificate: cliData.certificate + email: cliData.email } } diff --git a/src/config/controller.yaml b/src/config/controller.yaml index 8f1b8756..cd93ad6d 100644 --- a/src/config/controller.yaml +++ b/src/config/controller.yaml @@ -50,6 +50,7 @@ settings: # defaultJobInterval: 120 # Default job interval in seconds fogStatusUpdateInterval: 30 # Fog status update interval in seconds fogStatusUpdateTolerance: 3 # Fog status update tolerance + fogExpiredTokenCleanupInterval: 300 # Fog expired token cleanup interval in seconds # Database Configuration database: diff --git a/src/config/env-mapping.js b/src/config/env-mapping.js index 18f1baea..d4365fb5 100644 --- a/src/config/env-mapping.js +++ b/src/config/env-mapping.js @@ -38,6 +38,7 @@ module.exports = { // Settings Configuration 'FOG_STATUS_UPDATE_INTERVAL': 'settings.fogStatusUpdateInterval', 'FOG_STATUS_UPDATE_TOLERANCE': 'settings.fogStatusUpdateTolerance', + 'FOG_EXPIRED_TOKEN_CLEANUP_INTERVAL': 'settings.fogExpiredTokenCleanupInterval', // Database Configuration 'DB_PROVIDER': 'database.provider', diff --git a/src/data/migrations/mysql/db_migration_mysql_v1.0.4.sql b/src/data/migrations/mysql/db_migration_mysql_v1.0.5.sql similarity index 99% rename from src/data/migrations/mysql/db_migration_mysql_v1.0.4.sql rename to src/data/migrations/mysql/db_migration_mysql_v1.0.5.sql index 1be5d278..b0e86802 100644 --- a/src/data/migrations/mysql/db_migration_mysql_v1.0.4.sql +++ b/src/data/migrations/mysql/db_migration_mysql_v1.0.5.sql @@ -14,9 +14,6 @@ CREATE TABLE IF NOT EXISTS Registries ( id INT AUTO_INCREMENT PRIMARY KEY, url VARCHAR(255), is_public BOOLEAN, - secure BOOLEAN, - certificate TEXT, - requires_cert BOOLEAN, user_name TEXT, password TEXT, user_email TEXT @@ -812,4 +809,8 @@ ALTER TABLE MicroserviceStatuses ADD COLUMN health_status TEXT; ALTER TABLE Microservices ADD COLUMN is_activated BOOLEAN DEFAULT true; +ALTER TABLE Microservices ADD COLUMN host_network_mode BOOLEAN DEFAULT false; +ALTER TABLE Microservices ADD COLUMN is_privileged BOOLEAN DEFAULT false; +ALTER TABLE Microservices DROP COLUMN root_host_access; + COMMIT; \ No newline at end of file diff --git a/src/data/migrations/postgres/db_migration_pg_v1.0.4.sql b/src/data/migrations/postgres/db_migration_pg_v1.0.5.sql similarity index 99% rename from src/data/migrations/postgres/db_migration_pg_v1.0.4.sql rename to src/data/migrations/postgres/db_migration_pg_v1.0.5.sql index 3181cc00..09d6404b 100644 --- a/src/data/migrations/postgres/db_migration_pg_v1.0.4.sql +++ b/src/data/migrations/postgres/db_migration_pg_v1.0.5.sql @@ -12,9 +12,6 @@ CREATE TABLE IF NOT EXISTS "Registries" ( id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, url VARCHAR(255), is_public BOOLEAN, - secure BOOLEAN, - certificate TEXT, - requires_cert BOOLEAN, user_name TEXT, password TEXT, user_email TEXT @@ -810,4 +807,8 @@ CREATE INDEX idx_microservice_health_check_microservice_uuid ON "MicroserviceHea ALTER TABLE "MicroserviceStatuses" ADD COLUMN health_status TEXT; -ALTER TABLE "Microservices" ADD COLUMN is_activated BOOLEAN DEFAULT true; \ No newline at end of file +ALTER TABLE "Microservices" ADD COLUMN is_activated BOOLEAN DEFAULT true; + +ALTER TABLE "Microservices" ADD COLUMN host_network_mode BOOLEAN DEFAULT false; +ALTER TABLE "Microservices" ADD COLUMN is_privileged BOOLEAN DEFAULT false; +ALTER TABLE "Microservices" DROP COLUMN root_host_access; diff --git a/src/data/migrations/sqlite/db_migration_sqlite_v1.0.4.sql b/src/data/migrations/sqlite/db_migration_sqlite_v1.0.5.sql similarity index 99% rename from src/data/migrations/sqlite/db_migration_sqlite_v1.0.4.sql rename to src/data/migrations/sqlite/db_migration_sqlite_v1.0.5.sql index 13d21c08..ab609d82 100644 --- a/src/data/migrations/sqlite/db_migration_sqlite_v1.0.4.sql +++ b/src/data/migrations/sqlite/db_migration_sqlite_v1.0.5.sql @@ -12,9 +12,6 @@ CREATE TABLE IF NOT EXISTS Registries ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, url VARCHAR(255), is_public BOOLEAN, - secure BOOLEAN, - certificate TEXT, - requires_cert BOOLEAN, user_name TEXT, password TEXT, user_email TEXT @@ -797,4 +794,7 @@ CREATE INDEX idx_microservice_health_check_microservice_uuid ON MicroserviceHeal ALTER TABLE MicroserviceStatuses ADD COLUMN health_status TEXT; -ALTER TABLE Microservices ADD COLUMN is_activated BOOLEAN DEFAULT true; \ No newline at end of file +ALTER TABLE Microservices ADD COLUMN is_activated BOOLEAN DEFAULT true; + +ALTER TABLE Microservices ADD COLUMN host_network_mode BOOLEAN DEFAULT false; +ALTER TABLE Microservices ADD COLUMN is_privileged BOOLEAN DEFAULT false; diff --git a/src/data/models/microservice.js b/src/data/models/microservice.js index e1128093..8278d10e 100644 --- a/src/data/models/microservice.js +++ b/src/data/models/microservice.js @@ -37,9 +37,14 @@ module.exports = (sequelize, DataTypes) => { field: 'rebuild', defaultValue: false }, - rootHostAccess: { + hostNetworkMode: { type: DataTypes.BOOLEAN, - field: 'root_host_access', + field: 'host_network_mode', + defaultValue: false + }, + isPrivileged: { + type: DataTypes.BOOLEAN, + field: 'is_privileged', defaultValue: false }, runAsUser: { diff --git a/src/data/models/registry.js b/src/data/models/registry.js index 15295fba..fe169e51 100644 --- a/src/data/models/registry.js +++ b/src/data/models/registry.js @@ -16,18 +16,6 @@ module.exports = (sequelize, DataTypes) => { type: DataTypes.BOOLEAN, field: 'is_public' }, - isSecure: { - type: DataTypes.BOOLEAN, - field: 'secure' - }, - certificate: { - type: DataTypes.TEXT, - field: 'certificate' - }, - requiresCert: { - type: DataTypes.BOOLEAN, - field: 'requires_cert' - }, username: { type: DataTypes.TEXT, field: 'user_name' diff --git a/src/data/providers/database-provider.js b/src/data/providers/database-provider.js index fd6b899c..941edff7 100644 --- a/src/data/providers/database-provider.js +++ b/src/data/providers/database-provider.js @@ -251,8 +251,8 @@ class DatabaseProvider { // SQLite migration async runMigrationSQLite (dbName) { - const migrationSqlPath = path.resolve(__dirname, '../migrations/sqlite/db_migration_sqlite_v1.0.4.sql') - const migrationVersion = '1.0.4' + const migrationSqlPath = path.resolve(__dirname, '../migrations/sqlite/db_migration_sqlite_v1.0.5.sql') + const migrationVersion = '1.0.5' if (!fs.existsSync(migrationSqlPath)) { logger.error(`Migration file not found: ${migrationSqlPath}`) @@ -324,8 +324,8 @@ class DatabaseProvider { // MySQL migration async runMigrationMySQL (db) { - const migrationSqlPath = path.resolve(__dirname, '../migrations/mysql/db_migration_mysql_v1.0.4.sql') - const migrationVersion = '1.0.4' + const migrationSqlPath = path.resolve(__dirname, '../migrations/mysql/db_migration_mysql_v1.0.5.sql') + const migrationVersion = '1.0.5' if (!fs.existsSync(migrationSqlPath)) { logger.error(`Migration file not found: ${migrationSqlPath}`) @@ -385,8 +385,8 @@ class DatabaseProvider { // PostgreSQL migration async runMigrationPostgres (db) { - const migrationSqlPath = path.resolve(__dirname, '../migrations/postgres/db_migration_pg_v1.0.4.sql') - const migrationVersion = '1.0.4' + const migrationSqlPath = path.resolve(__dirname, '../migrations/postgres/db_migration_pg_v1.0.5.sql') + const migrationVersion = '1.0.5' if (!fs.existsSync(migrationSqlPath)) { logger.error(`Migration file not found: ${migrationSqlPath}`) diff --git a/src/data/seeders/mysql/db_seeder_mysql_v1.0.2.sql b/src/data/seeders/mysql/db_seeder_mysql_v1.0.2.sql index 5675a835..d73d393e 100644 --- a/src/data/seeders/mysql/db_seeder_mysql_v1.0.2.sql +++ b/src/data/seeders/mysql/db_seeder_mysql_v1.0.2.sql @@ -1,9 +1,9 @@ START TRANSACTION; -INSERT INTO `Registries` (url, is_public, secure, certificate, requires_cert, user_name, password, user_email) +INSERT INTO `Registries` (url, is_public, user_name, password, user_email) VALUES - ('registry.hub.docker.com', true, true, '', false, '', '', ''), - ('from_cache', true, true, '', false, '', '', ''); + ('registry.hub.docker.com', true, '', '', ''), + ('from_cache', true, '', '', ''); INSERT INTO `CatalogItems` (name, description, category, publisher, disk_required, ram_required, picture, config_example, is_public, registry_id) VALUES diff --git a/src/data/seeders/postgres/db_seeder_pg_v1.0.2.sql b/src/data/seeders/postgres/db_seeder_pg_v1.0.2.sql index 37a361f4..ca8d0821 100644 --- a/src/data/seeders/postgres/db_seeder_pg_v1.0.2.sql +++ b/src/data/seeders/postgres/db_seeder_pg_v1.0.2.sql @@ -1,9 +1,9 @@ START TRANSACTION; -INSERT INTO "Registries" (url, is_public, secure, certificate, requires_cert, user_name, password, user_email) +INSERT INTO "Registries" (url, is_public, user_name, password, user_email) VALUES - ('registry.hub.docker.com', true, true, '', false, '', '', ''), - ('from_cache', true, true, '', false, '', '', ''); + ('registry.hub.docker.com', true, '', '', ''), + ('from_cache', true, '', '', ''); INSERT INTO "CatalogItems" (name, description, category, publisher, disk_required, ram_required, picture, config_example, is_public, registry_id) VALUES diff --git a/src/data/seeders/sqlite/db_seeder_sqlite_v1.0.2.sql b/src/data/seeders/sqlite/db_seeder_sqlite_v1.0.2.sql index d3e6e162..80d4ee2c 100644 --- a/src/data/seeders/sqlite/db_seeder_sqlite_v1.0.2.sql +++ b/src/data/seeders/sqlite/db_seeder_sqlite_v1.0.2.sql @@ -1,7 +1,7 @@ -INSERT INTO `Registries` (url, is_public, secure, certificate, requires_cert, user_name, password, user_email) +INSERT INTO `Registries` (url, is_public, user_name, password, user_email) VALUES - ('registry.hub.docker.com', true, true, '', false, '', '', ''), - ('from_cache', true, true, '', false, '', '', ''); + ('registry.hub.docker.com', true, '', '', ''), + ('from_cache', true, '', '', ''); INSERT INTO `CatalogItems` (name, description, category, publisher, disk_required, ram_required, picture, config_example, is_public, registry_id) VALUES diff --git a/src/helpers/error-messages.js b/src/helpers/error-messages.js index 9966ca14..88131689 100644 --- a/src/helpers/error-messages.js +++ b/src/helpers/error-messages.js @@ -79,6 +79,8 @@ module.exports = { REGISTRY_NOT_FOUND: 'Registry not found', USER_ALREADY_ACTIVATED: 'User is already activated.', USER_NOT_ACTIVATED_YET: 'User is not activated yet.', + REGISTRY_IS_SYSTEM: 'Registry is system and can\'t be updated or deleted', + REGISTRY_IS_IN_USE: 'Registry is in use by microservices and can\'t be deleted', CLI: { INVALID_PORT_MAPPING: 'Port mapping parsing error. Please provide valid port mapping.', INVALID_VOLUME_MAPPING: 'Volume mapping parsing error. Please provide valid volume mapping.', diff --git a/src/jobs/fog-status-job.js b/src/jobs/fog-status-job.js index 6f96ff7a..2d1f167c 100644 --- a/src/jobs/fog-status-job.js +++ b/src/jobs/fog-status-job.js @@ -21,6 +21,7 @@ const MicroserviceService = require('../services/microservices-service') const { microserviceState, microserviceExecState } = require('../enums/microservice-state') const FogStates = require('../enums/fog-state') const Config = require('../config') +const logger = require('../logger') const scheduleTime = Config.get('settings.fogStatusUpdateInterval') * 1000 @@ -29,7 +30,7 @@ async function run () { const _updateFogsConnectionStatus = TransactionDecorator.generateTransaction(updateFogsConnectionStatus) await _updateFogsConnectionStatus() } catch (error) { - console.error(error) + logger.error('Error during fog status update:', error) } finally { setTimeout(run, scheduleTime) } @@ -62,12 +63,36 @@ async function _updateFogStatus (transaction) { async function _updateMicroserviceStatus (unknownFogUuids, transaction) { const microservices = await MicroserviceManager.findAllWithStatuses({ iofogUuid: unknownFogUuids }, transaction) + + // Filter out inactive microservices that are already STOPPED - they should not be updated to UNKNOWN const microserviceStatusIds = microservices - .filter((microservice) => microservice.microserviceStatus) + .filter((microservice) => { + // Skip if no microservice status + if (!microservice.microserviceStatus) { + return false + } + // Skip if microservice is inactive and already STOPPED + if (!microservice.isActivated && microservice.microserviceStatus.status === microserviceState.STOPPED) { + return false + } + return true + }) .map((microservice) => microservice.microserviceStatus.id) + const microserviceExecStatusIds = microservices - .filter((microservice) => microservice.microserviceExecStatus) + .filter((microservice) => { + // Skip if no exec status + if (!microservice.microserviceExecStatus) { + return false + } + // Skip if microservice is inactive and already STOPPED + if (!microservice.isActivated && microservice.microserviceStatus && microservice.microserviceStatus.status === microserviceState.STOPPED) { + return false + } + return true + }) .map((microservice) => microservice.microserviceExecStatus.id) + await MicroserviceStatusManager.update({ id: microserviceStatusIds }, { status: microserviceState.UNKNOWN }, transaction) await MicroserviceExecStatusManager.update({ id: microserviceExecStatusIds }, { execSesssionId: '', status: microserviceExecState.INACTIVE }, transaction) return microservices diff --git a/src/jobs/fog-token-cleanup-job.js b/src/jobs/fog-token-cleanup-job.js new file mode 100644 index 00000000..1cce9459 --- /dev/null +++ b/src/jobs/fog-token-cleanup-job.js @@ -0,0 +1,42 @@ +/* + * ******************************************************************************* + * * Copyright (c) 2023 Datasance Teknoloji A.S. + * * + * * This program and the accompanying materials are made available under the + * * terms of the Eclipse Public License v. 2.0 which is available at + * * http://www.eclipse.org/legal/epl-2.0 + * * + * * SPDX-License-Identifier: EPL-2.0 + * ******************************************************************************* + * + */ + +const FogUsedTokenManager = require('../data/managers/fog-used-token-manager') +const Config = require('../config') +const logger = require('../logger') + +const scheduleTime = Config.get('settings.fogExpiredTokenCleanupInterval') * 1000 + +async function run () { + try { + await cleanupExpiredTokens() + } catch (error) { + logger.error('Error during JTI cleanup:', error) + } finally { + setTimeout(run, scheduleTime) + } +} + +async function cleanupExpiredTokens () { + try { + logger.debug('Starting cleanup of expired JTIs') + const count = await FogUsedTokenManager.cleanupExpiredJtis() + logger.debug(`Cleaned up ${count} expired JTIs`) + } catch (error) { + logger.error('Error during JTI cleanup:', error) + } +} + +module.exports = { + run +} diff --git a/src/jobs/stopped-app-status-job.js b/src/jobs/stopped-app-status-job.js index 05a5403d..ea07f2bd 100644 --- a/src/jobs/stopped-app-status-job.js +++ b/src/jobs/stopped-app-status-job.js @@ -20,6 +20,7 @@ const { microserviceState, microserviceExecState } = require('../enums/microserv const Config = require('../config') const ApplicationManager = require('../data/managers/application-manager') +const logger = require('../logger') const scheduleTime = Config.get('settings.fogStatusUpdateInterval') * 1000 @@ -33,7 +34,7 @@ async function run () { // Handle individually deactivated microservices await _updateStoppedMicroserviceStatus() } catch (error) { - console.error(error) + logger.error('Error during stopped application status update:', error) } finally { setTimeout(run, scheduleTime) } diff --git a/src/schemas/iofog.js b/src/schemas/iofog.js index eaf608bc..c2246808 100644 --- a/src/schemas/iofog.js +++ b/src/schemas/iofog.js @@ -245,13 +245,6 @@ const defaultRouterCreate = { 'messagingPort': { 'type': 'integer', 'minimum': 1, 'maximum': 65535 }, 'interRouterPort': { 'type': 'integer', 'minimum': 1, 'maximum': 65535 }, 'edgeRouterPort': { 'type': 'integer', 'minimum': 1, 'maximum': 65535 }, - 'requireSsl': { 'type': 'string' }, - 'sslProfile': { 'type': 'string' }, - 'saslMechanisms': { 'type': 'string' }, - 'authenticatePeer': { 'type': 'string' }, - 'caCert': { 'type': 'string' }, - 'tlsCert': { 'type': 'string' }, - 'tlsKey': { 'type': 'string' }, 'host': { 'type': 'string' } }, 'required': ['host'], diff --git a/src/schemas/microservice.js b/src/schemas/microservice.js index 4ec80352..670c491d 100644 --- a/src/schemas/microservice.js +++ b/src/schemas/microservice.js @@ -30,7 +30,8 @@ const microserviceCreate = { }, 'iofogUuid': { 'type': 'string' }, 'agentName': { 'type': 'string' }, - 'rootHostAccess': { 'type': 'boolean' }, + 'hostNetworkMode': { 'type': 'boolean' }, + 'isPrivileged': { 'type': 'boolean' }, 'schedule': { 'type': 'integer', 'minimum': 0, @@ -100,7 +101,8 @@ const microserviceUpdate = { 'rebuild': { 'type': 'boolean' }, 'iofogUuid': { 'type': 'string' }, 'agentName': { 'type': 'string' }, - 'rootHostAccess': { 'type': 'boolean' }, + 'hostNetworkMode': { 'type': 'boolean' }, + 'isPrivileged': { 'type': 'boolean' }, 'logSize': { 'type': 'integer', 'minimum': 0 }, 'schedule': { 'type': 'integer', diff --git a/src/schemas/registry.js b/src/schemas/registry.js index 695c936f..4e31e986 100644 --- a/src/schemas/registry.js +++ b/src/schemas/registry.js @@ -23,9 +23,7 @@ const registryCreate = { 'type': 'string', 'pattern': '^(([^<>()\\[\\]\\\\.,;:\\s@"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}' + '\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$' - }, - 'requiresCert': { 'type': 'boolean' }, - 'certificate': { 'type': 'string' } + } }, 'required': ['url', 'isPublic', 'username', 'password', 'email'], 'additionalProperties': true @@ -53,9 +51,7 @@ const registryUpdate = { 'type': 'string', 'pattern': '^(([^<>()\\[\\]\\\\.,;:\\s@"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}' + '\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$' - }, - 'requiresCert': { 'type': 'boolean' }, - 'certificate': { 'type': 'string' } + } }, 'additionalProperties': true } diff --git a/src/schemas/secret.js b/src/schemas/secret.js index 6b52e5eb..3a370c67 100644 --- a/src/schemas/secret.js +++ b/src/schemas/secret.js @@ -15,6 +15,7 @@ const secretUpdate = { type: 'object', properties: { name: { type: 'string', minLength: 1, maxLength: 255 }, + type: { type: 'string', enum: ['Opaque', 'tls'] }, data: { type: 'object' } }, required: ['data'], diff --git a/src/server.js b/src/server.js index 25a7e387..5cae2fff 100755 --- a/src/server.js +++ b/src/server.js @@ -17,7 +17,6 @@ initialize().then(() => { const config = require('./config') const logger = require('./logger') const db = require('./data/models') - const CleanupService = require('./services/cleanup-service') const WebSocketServer = require('./websocket/server') const bodyParser = require('body-parser') @@ -269,9 +268,6 @@ initialize().then(() => { fs.writeFileSync(ecnViewerControllerConfigFilePath, ecnViewerConfigScript) } - // Initialize cleanup service - CleanupService.start() - initState() .then(() => { if (hasFileBasedSSL) { diff --git a/src/services/agent-service.js b/src/services/agent-service.js index 5e2208dd..0fbd0705 100644 --- a/src/services/agent-service.js +++ b/src/services/agent-service.js @@ -15,9 +15,9 @@ const config = require('../config') const path = require('path') const fs = require('fs') const formidable = require('formidable') -const Sequelize = require('sequelize') +// const Sequelize = require('sequelize') const moment = require('moment') -const Op = Sequelize.Op +// const Op = Sequelize.Op const logger = require('../logger') const TransactionDecorator = require('../decorators/transaction-decorator') @@ -411,7 +411,8 @@ const getAgentMicroservices = async function (fog, transaction) { config: microservice.config, annotations: microservice.annotations, rebuild: microservice.rebuild, - rootHostAccess: microservice.rootHostAccess, + hostNetworkMode: microservice.hostNetworkMode, + isPrivileged: microservice.isPrivileged, cpuSetCpus: microservice.cpuSetCpus, memoryLimit: microservice.memoryLimit, healthCheck: healthCheck, @@ -493,14 +494,7 @@ const getAgentMicroservice = async function (microserviceUuid, fog, transaction) } const getAgentRegistries = async function (fog, transaction) { - const registries = await RegistryManager.findAll({ - [Op.or]: - [ - { - isPublic: true - } - ] - }, transaction) + const registries = await RegistryManager.findAll({}, transaction) return { registries: registries } diff --git a/src/services/catalog-service.js b/src/services/catalog-service.js index 8350c19c..dcd36ac9 100644 --- a/src/services/catalog-service.js +++ b/src/services/catalog-service.js @@ -24,11 +24,12 @@ const Op = require('sequelize').Op const Validator = require('../schemas/index') const RegistryManager = require('../data/managers/registry-manager') const MicroserviceManager = require('../data/managers/microservice-manager') -const MicroseriveStates = require('../enums/microservice-state') +// const MicroseriveStates = require('../enums/microservice-state') +const ChangeTrackingService = require('./change-tracking-service') const createCatalogItemEndPoint = async function (data, transaction) { await Validator.validate(data, Validator.schemas.catalogItemCreate) - await _checkForDuplicateName(data.name, transaction) + await _checkForDuplicateName(data.name, null, transaction) await _checkForRestrictedPublisher(data.publisher) const catalogItem = await _createCatalogItem(data, transaction) await _createCatalogImages(data, catalogItem, transaction) @@ -129,6 +130,11 @@ const deleteCatalogItemEndPoint = async function (id, isCLI, transaction) { throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.SYSTEM_CATALOG_ITEM_DELETE, id)) } + const microservices = await MicroserviceManager.findAllWithStatuses({ catalogItemId: id }, transaction) + if (microservices.length > 0) { + throw new Errors.ValidationError(ErrorMessages.CATALOG_ITEM_IMAGES_IS_FROZEN) + } + const affectedRows = await CatalogItemManager.delete(where, transaction) if (affectedRows === 0) { throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_CATALOG_ITEM_ID, id)) @@ -183,7 +189,7 @@ async function getHalCatalogItem (transaction) { const _checkForDuplicateName = async function (name, item, transaction) { if (name) { - const where = item.id + const where = (item && item.id) ? { name: name, id: { [Op.ne]: item.id } } : { name: name } @@ -314,6 +320,12 @@ const _updateCatalogItem = async function (data, where, transaction) { if (!registry) { throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_REGISTRY_ID, data.registryId)) } + const microservices = await MicroserviceManager.findAllWithStatuses({ catalogItemId: data.id }, transaction) + if (microservices.length > 0) { + for (const ms of microservices) { + await MicroserviceManager.updateAndFind({ uuid: ms.uuid }, { registryId: data.registryId }, transaction) + } + } } const item = await _checkIfItemExists(where, transaction) @@ -328,12 +340,13 @@ const _updateCatalogItem = async function (data, where, transaction) { const _updateCatalogItemImages = async function (data, transaction) { if (data.images) { - const microservices = await MicroserviceManager.findAllWithStatuses({ catalogItemId: data.id }, transaction) - for (const ms of microservices) { - if (ms.microserviceStatus.status === MicroseriveStates.RUNNING) { - throw new Errors.ValidationError(ErrorMessages.CATALOG_ITEM_IMAGES_IS_FROZEN) - } - } + // TODO: Rather than not allowing images for running microservices, update changetracking for agent microsevice list so that once catalog item images are updated, the microservices are updated and restarted. + // const microservices = await MicroserviceManager.findAllWithStatuses({ catalogItemId: data.id }, transaction) + // for (const ms of microservices) { + // if (ms.microserviceStatus.status === MicroseriveStates.RUNNING) { + // throw new Errors.ValidationError(ErrorMessages.CATALOG_ITEM_IMAGES_IS_FROZEN) + // } + // } for (const image of data.images) { await CatalogItemImageManager.updateOrCreate({ @@ -345,6 +358,13 @@ const _updateCatalogItemImages = async function (data, transaction) { containerImage: image.containerImage }, transaction) } + const microservices = await MicroserviceManager.findAllWithStatuses({ catalogItemId: data.id }, transaction) + if (microservices.length > 0) { + for (const ms of microservices) { + await MicroserviceManager.updateAndFind({ uuid: ms.uuid }, { rebuild: true }, transaction) + await ChangeTrackingService.update(ms.iofogUuid, ChangeTrackingService.events.microserviceCommon, transaction) + } + } } } diff --git a/src/services/certificate-service.js b/src/services/certificate-service.js index 316062bc..e0e6b35e 100644 --- a/src/services/certificate-service.js +++ b/src/services/certificate-service.js @@ -215,7 +215,7 @@ async function deleteCAEndpoint (name, transaction) { // Delete certificate record and the secret await CertificateManager.deleteCertificate(name, transaction) - await SecretService.deleteSecretEndpoint(name) + await SecretService.deleteSecretEndpoint(name, transaction) return {} } @@ -420,15 +420,12 @@ async function deleteCertificateEndpoint (name, transaction) { // Check if this is a CA with signed certificates if (certRecord.isCA) { - const signedCerts = await CertificateManager.findCertificatesByCA(certRecord.id, transaction) - if (signedCerts.length > 0) { - throw new Errors.ValidationError(`Cannot delete CA that has signed certificates. Please delete the following certificates first: ${signedCerts.map(cert => cert.name).join(', ')}`) - } + throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.CERTIFICATE_NOT_FOUND, name)) } // Delete certificate record and the secret await CertificateManager.deleteCertificate(name, transaction) - await SecretService.deleteSecretEndpoint(name) + await SecretService.deleteSecretEndpoint(name, transaction) return {} } diff --git a/src/services/cleanup-service.js b/src/services/cleanup-service.js deleted file mode 100644 index 9c67201d..00000000 --- a/src/services/cleanup-service.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ - -const schedule = require('node-schedule') -const FogUsedTokenManager = require('../data/managers/fog-used-token-manager') -const logger = require('../logger') - -class CleanupService { - start () { - // Run every 5 minutes to ensure we catch all expired tokens - // (since tokens are valid for 10 minutes) - schedule.scheduleJob('*/5 * * * *', async () => { - try { - logger.debug('Starting cleanup of expired JTIs') - const count = await FogUsedTokenManager.cleanupExpiredJtis() - logger.debug(`Cleaned up ${count} expired JTIs`) - } catch (error) { - logger.error('Error during JTI cleanup:', error) - } - }) - } -} - -module.exports = new CleanupService() diff --git a/src/services/config-map-service.js b/src/services/config-map-service.js index 1ccf0f0d..a1aa48c4 100644 --- a/src/services/config-map-service.js +++ b/src/services/config-map-service.js @@ -13,6 +13,9 @@ const TransactionDecorator = require('../decorators/transaction-decorator') const ConfigMapManager = require('../data/managers/config-map-manager') +const MicroserviceManager = require('../data/managers/microservice-manager') +const MicroserviceEnvManager = require('../data/managers/microservice-env-manager') +const ChangeTrackingService = require('./change-tracking-service') const AppHelper = require('../helpers/app-helper') const Errors = require('../helpers/errors') const ErrorMessages = require('../helpers/error-messages') @@ -58,6 +61,7 @@ async function updateConfigMapEndpoint (configMapName, configMapData, transactio const configMap = await ConfigMapManager.updateConfigMap(configMapName, configMapData.immutable, configMapData.data, transaction) await _updateChangeTrackingForFogs(configMapName, transaction) + await _updateMicroservicesUsingConfigMap(configMapName, transaction) return { id: configMap.id, name: configMap.name, @@ -102,9 +106,19 @@ async function deleteConfigMapEndpoint (configMapName, transaction) { } await ConfigMapManager.deleteConfigMap(configMapName, transaction) + await _deleteVolumeMountsUsingConfigMap(configMapName, transaction) return {} } +async function _deleteVolumeMountsUsingConfigMap (configMapName, transaction) { + const volumeMounts = await VolumeMountingManager.findAll({ configMapName: configMapName }, transaction) + if (volumeMounts.length > 0) { + for (const volumeMount of volumeMounts) { + await VolumeMountService.deleteVolumeMountEndpoint(volumeMount.name, transaction) + } + } +} + async function _updateChangeTrackingForFogs (configMapName, transaction) { const configMapVolumeMounts = await VolumeMountingManager.findAll({ configMapName: configMapName }, transaction) if (configMapVolumeMounts.length > 0) { @@ -118,6 +132,57 @@ async function _updateChangeTrackingForFogs (configMapName, transaction) { } } +async function _updateMicroservicesUsingConfigMap (configMapName, transaction) { + // Find all microservice environment variables that use this config map + const envVars = await MicroserviceEnvManager.findAll({ + valueFromConfigMap: { [require('sequelize').Op.like]: `${configMapName}/%` } + }, transaction) + + if (envVars.length === 0) { + return + } + + // Get the updated config map data + const configMap = await ConfigMapManager.getConfigMap(configMapName, transaction) + if (!configMap) { + return + } + + // Group environment variables by microservice UUID + const microserviceEnvMap = new Map() + for (const envVar of envVars) { + if (!microserviceEnvMap.has(envVar.microserviceUuid)) { + microserviceEnvMap.set(envVar.microserviceUuid, []) + } + microserviceEnvMap.get(envVar.microserviceUuid).push(envVar) + } + + // Update each microservice's environment variables and change tracking + for (const [microserviceUuid, envVars] of microserviceEnvMap) { + // Get the microservice to access its iofogUuid + const microservice = await MicroserviceManager.findOne({ uuid: microserviceUuid }, transaction) + if (!microservice) { + continue + } + + // Update each environment variable with the new config map data + for (const envVar of envVars) { + const [configMapNameFromRef, dataKey] = envVar.valueFromConfigMap.split('/') + if (configMapNameFromRef === configMapName && configMap.data[dataKey]) { + // Update the environment variable value with the new config map data + await MicroserviceEnvManager.update( + { id: envVar.id }, + { value: configMap.data[dataKey] }, + transaction + ) + } + } + + // Update change tracking for the microservice's fog node + await ChangeTrackingService.update(microservice.iofogUuid, ChangeTrackingService.events.microserviceCommon, transaction) + } +} + module.exports = { createConfigMapEndpoint: TransactionDecorator.generateTransaction(createConfigMapEndpoint), updateConfigMapEndpoint: TransactionDecorator.generateTransaction(updateConfigMapEndpoint), diff --git a/src/services/iofog-service.js b/src/services/iofog-service.js index 50229608..4e465b42 100644 --- a/src/services/iofog-service.js +++ b/src/services/iofog-service.js @@ -62,17 +62,19 @@ async function getLocalCertificateHosts (isKubernetes, namespace) { return '127.0.0.1,localhost,host.docker.internal,host.containers.internal' } -async function getSiteCertificateHosts (fogData, transaction) { +async function getSiteCertificateHosts (fogData, fogUuid, transaction) { const hosts = new Set() - // Add existing hosts if isSystem - if (fogData.isSystem) { + const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) + const isFogDefaultRouter = fogUuid === defaultRouter.iofogUuid + // Add existing hosts if isSystem and fog is default-router + if (fogData.isSystem && isFogDefaultRouter) { if (fogData.host) hosts.add(fogData.host) if (fogData.ipAddress) hosts.add(fogData.ipAddress) if (fogData.ipAddressExternal) hosts.add(fogData.ipAddressExternal) } - // Add default router host if not system - if (!fogData.isSystem) { - const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) + // Add default router host if not system or fog isSystem but not default-router + if (!fogData.isSystem || (fogData.isSystem && !isFogDefaultRouter)) { + // const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) if (defaultRouter.host) hosts.add(defaultRouter.host) } // Add upstream router hosts @@ -197,7 +199,7 @@ async function _handleRouterCertificates (fogData, uuid, isRouterModeChanged, tr // For other router modes, ensure all other certificates // Always ensure site-server cert exists logger.debug('Ensuring site-server certificate exists') - const siteHosts = await getSiteCertificateHosts(fogData, transaction) + const siteHosts = await getSiteCertificateHosts(fogData, uuid, transaction) await ensureCert( `${uuid}-site-server`, `${uuid}-site-server`, @@ -298,10 +300,10 @@ async function createFogEndPoint (fogData, isCLI, transaction) { throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.INVALID_ROUTER_MODE, fogData.routerMode)) } - // TODO: handle multiple system fogs a.k.a multi-remote-controller and multi interior routers - if (fogData.isSystem && !!(await FogManager.findOne({ isSystem: true }, transaction))) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.DUPLICATE_SYSTEM_FOG)) - } + // // TODO: handle multiple system fogs a.k.a multi-remote-controller and multi interior routers + // if (fogData.isSystem && !!(await FogManager.findOne({ isSystem: true }, transaction))) { + // throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.DUPLICATE_SYSTEM_FOG)) + // } const existingFog = await FogManager.findOne({ name: createFogData.name }, transaction) if (existingFog) { @@ -1079,7 +1081,8 @@ async function _createHalMicroserviceForFog (fogData, oldFog, transaction) { config: '{}', catalogItemId: halItem.id, iofogUuid: fogData.uuid, - rootHostAccess: true, + hostNetworkMode: true, + isPrivileged: true, logSize: Constants.MICROSERVICE_DEFAULT_LOG_SIZE, schedule: 1, configLastUpdated: Date.now() @@ -1124,7 +1127,8 @@ async function _createBluetoothMicroserviceForFog (fogData, oldFog, transaction) config: '{}', catalogItemId: bluetoothItem.id, iofogUuid: fogData.uuid, - rootHostAccess: true, + hostNetworkMode: true, + isPrivileged: true, logSize: Constants.MICROSERVICE_DEFAULT_LOG_SIZE, schedule: 1, configLastUpdated: Date.now() @@ -1187,7 +1191,8 @@ async function enableNodeExecEndPoint (execData, isCLI, transaction) { iofogUuid: execData.uuid, ipcMode: 'host', pidMode: 'host', - rootHostAccess: true, + hostNetworkMode: true, + isPrivileged: true, logSize: Constants.MICROSERVICE_DEFAULT_LOG_SIZE, schedule: 0, execEnabled: true, @@ -1228,7 +1233,8 @@ async function enableNodeExecEndPoint (execData, isCLI, transaction) { const updateData = { ipcMode: debugMicroserviceData.ipcMode, pidMode: debugMicroserviceData.pidMode, - rootHostAccess: debugMicroserviceData.rootHostAccess, + hostNetworkMode: debugMicroserviceData.hostNetworkMode, + isPrivileged: debugMicroserviceData.isPrivileged, logSize: debugMicroserviceData.logSize, schedule: debugMicroserviceData.schedule, configLastUpdated: debugMicroserviceData.configLastUpdated, diff --git a/src/services/microservice-ports/default.js b/src/services/microservice-ports/default.js deleted file mode 100644 index 956186be..00000000 --- a/src/services/microservice-ports/default.js +++ /dev/null @@ -1,565 +0,0 @@ -/* only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed - * ******************************************************************************* - * * Copyright (c) 2023 Datasance Teknoloji A.S. - * * - * * This program and the accompanying materials are made available under the - * * terms of the Eclipse Public License v. 2.0 which is available at - * * http://www.eclipse.org/legal/epl-2.0 - * * - * * SPDX-License-Identifier: EPL-2.0 - * ******************************************************************************* - * - */ - -const MicroservicePortManager = require('../../data/managers/microservice-port-manager') -const MicroserviceManager = require('../../data/managers/microservice-manager') -const MicroserviceStatusManager = require('../../data/managers/microservice-status-manager') -const ApplicationManager = require('../../data/managers/application-manager') -const ConfigManager = require('../../data/managers/config-manager') -const ChangeTrackingService = require('../change-tracking-service') -const AppHelper = require('../../helpers/app-helper') -const Errors = require('../../helpers/errors') -const ErrorMessages = require('../../helpers/error-messages') -const CatalogService = require('../../services/catalog-service') -const Op = require('sequelize').Op -const FogManager = require('../../data/managers/iofog-manager') -const RouterManager = require('../../data/managers/router-manager') -const MicroservicePublicPortManager = require('../../data/managers/microservice-public-port-manager') -const MicroserviceExtraHostManager = require('../../data/managers/microservice-extra-host-manager') -const controllerConfig = require('../../config') - -const { MICROSERVICE_DEFAULT_LOG_SIZE, DEFAULT_ROUTER_NAME, DEFAULT_PROXY_HOST, RESERVED_PORTS } = require('../../helpers/constants') - -const lget = require('lodash/get') - -async function _checkForDuplicatePorts (agent, localPort, transaction) { - if (RESERVED_PORTS.find(port => port === localPort)) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.PORT_RESERVED, localPort)) - } - - const microservices = await agent.getMicroservice() - for (const microservice of microservices) { - const ports = await microservice.getPorts() - if (ports.find(port => port.portExternal === localPort)) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.PORT_NOT_AVAILABLE, localPort)) - } - } - - const publicPorts = await MicroservicePublicPortManager.findAll({ hostId: agent.uuid }, transaction) - if (publicPorts.find(port => port.publicPort === localPort)) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.PORT_NOT_AVAILABLE, localPort)) - } -} - -function _createDefaultPublicPortRange () { - const defaultPortRangeStr = process.env.PUBLIC_PORTS_RANGE || controllerConfig.get('publicPorts.range') - const [startStr, endStr] = defaultPortRangeStr.split('-') - let start = parseInt(startStr) - let end = parseInt(endStr) - if (!start || Number.isNaN(start)) { start = 6001 } - if (!end || Number.isNaN(end) || end < start) { - end = start + 1998 - } - const size = end - start - const availablePorts = new Array(size) - for (let i = 0; i < size; ++i) { - availablePorts[i] = start + i - } - - return availablePorts -} - -// Validate port and populate mapping.publicHost, mapping.publicPort, mapping.localAgent -async function validatePortMapping (agent, mapping, availablePublicPortsByHost, transaction) { - await _checkForDuplicatePorts(agent, mapping.external, transaction) - - if (mapping.public) { - const isTcp = mapping.public.protocol ? mapping.public.protocol.toLowerCase() === 'tcp' : false - // Validate link protocol - for (const scheme of mapping.public.schemes) { - // !isTcp === HTTP link protocol will be used - if (!scheme.startsWith('http') && !isTcp) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.WRONG_PUBLIC_LINK_PROTOCOL, mapping.internal, scheme, 'http')) - } - } - let host - if (mapping.public.router && mapping.public.router.host && mapping.public.router.host !== DEFAULT_ROUTER_NAME) { - host = await FogManager.findOne({ uuid: mapping.public.router.host }, transaction) - if (!host) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.INVALID_ROUTER_HOST, mapping.public.host)) - } - } else { - host = await FogManager.findOne({ isSystem: true }, transaction) - if (!host) { - const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) - if (!defaultRouter) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.INVALID_ROUTER_HOST, DEFAULT_ROUTER_NAME)) - } - } - } - - // We have found a host - if (host) { - // Port is defined by user - if (mapping.public.router && mapping.public.router.port) { - await _checkForDuplicatePorts(host, mapping.public.router.port, transaction) - mapping.publicPort = mapping.public.router.port - } else { - // Assign next available public port - const currentPublicPorts = (await MicroservicePublicPortManager.findAll({ hostId: host.uuid }, transaction)).map(p => p.publicPort) - // Default range 6001 -> 7999 - availablePublicPortsByHost[host.uuid] = availablePublicPortsByHost[host.uuid] || _createDefaultPublicPortRange() - availablePublicPortsByHost[host.uuid] = availablePublicPortsByHost[host.uuid].filter(port => !currentPublicPorts.includes(port)) - if (availablePublicPortsByHost[host.uuid].length === 0) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.NO_AVAILABLE_PUBLIC_PORT, host.isSystem ? DEFAULT_ROUTER_NAME : host.name)) - } - mapping.publicPort = availablePublicPortsByHost[host.uuid].shift() - } - } else { - const hostId = 'default-router' - // We don't have a host. A.k.a, there is no System agent, but there is a default router. A.k.a: We're running on K8s - // Port is defined by user - if (mapping.public.router && mapping.public.router.port) { - // Alls ports are shared by the same proxy msvc - const publicPorts = await MicroservicePublicPortManager.findAll({ hostId: null }, transaction) - if (publicPorts.find(port => port.publicPort === mapping.public.router.port)) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.PORT_NOT_AVAILABLE, mapping.public.router.port)) - } - mapping.publicPort = mapping.public.router.port - } else { - // Port - // Alls ports are shared by the same proxy msvc - const currentPublicPorts = (await MicroservicePublicPortManager.findAll({ hostId: null }, transaction)).map(p => p.publicPort) - availablePublicPortsByHost[hostId] = availablePublicPortsByHost[hostId] || _createDefaultPublicPortRange() - availablePublicPortsByHost[hostId] = availablePublicPortsByHost[hostId].filter(port => !currentPublicPorts.includes(port)) - if (availablePublicPortsByHost[hostId].length === 0) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.NO_AVAILABLE_PUBLIC_PORT, host.isSystem ? DEFAULT_ROUTER_NAME : host.name)) - } - mapping.publicPort = availablePublicPortsByHost[hostId].shift() - } - } - - mapping.publicHost = host - mapping.localAgent = agent - } -} - -async function validatePortMappings (microserviceData, transaction) { - if (!microserviceData.ports || microserviceData.ports.length === 0) { - return - } - - const localAgent = await FogManager.findOne({ uuid: microserviceData.iofogUuid }, transaction) - if (!localAgent) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.INVALID_IOFOG_UUID, microserviceData.iofogUuid)) - } - - // Will be filled by validatePortMapping - // In memory store to keep track of newly allocated ports - const availablePublicPortsByHost = {} - for (const mapping of microserviceData.ports) { - await validatePortMapping(localAgent, mapping, availablePublicPortsByHost, transaction) - } -} - -async function validatePublicPortAppHostTemplate (extraHost, templateArgs, msvc, transaction) { - if (templateArgs.length !== 5) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.INVALID_HOST_TEMPLATE, templateArgs.join('.'))) - } - - const ports = await MicroservicePortManager.findAllPublicPorts({ microserviceUuid: msvc.uuid }, transaction) - - for (const port of ports) { - if (port.publicPort.publicPort === +(templateArgs[4])) { - if (port.publicPort.hostId) { - const fog = await FogManager.findOne({ uuid: port.publicPort.hostId }, transaction) - extraHost.publicPort = port.publicPort.publicPort - extraHost.targetFogUuid = fog.uuid - extraHost.value = fog.host || fog.ipAddress - } else { - extraHost.publicPort = port.publicPort.publicPort - extraHost.targetFogUuid = null - extraHost.value = lget( - await ConfigManager.findOne({ key: DEFAULT_PROXY_HOST }, transaction), - 'value', - 'undefined-proxy-host' - ) - } - return extraHost - } - } - - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.NOT_FOUND_HOST_TEMPLATE, templateArgs[4])) -} - -async function movePublicPortsToNewFog (updatedMicroservice, transaction) { - const portMappings = await updatedMicroservice.getPorts() - for (const portMapping of portMappings) { - if (!portMapping.isPublic) { - continue - } - - const publicPort = await portMapping.getPublicPort() - const localMapping = `amqp:${publicPort.queueName}=>${publicPort.protocol}:${portMapping.portExternal}` - const localProxy = await MicroserviceManager.findOne({ uuid: publicPort.localProxyId }, transaction) - await _updateOrDeleteProxyMicroservice(localProxy.uuid, localMapping, transaction) - - const destAgent = await FogManager.findOne({ uuid: updatedMicroservice.iofogUuid }, transaction) - const destAgentsRouter = destAgent.routerId ? await RouterManager.findOne({ id: destAgent.routerId }, transaction) : await RouterManager.findOne({ iofogUuid: destAgent.uuid }, transaction) - const networkRouter = { - host: 'localhost', - port: destAgentsRouter.messagingPort - } - const newProxy = await _createOrUpdateProxyMicroservice(localMapping, networkRouter, updatedMicroservice.iofogUuid, localProxy.catalogItemId, transaction) - publicPort.localProxyId = newProxy.uuid - await MicroservicePublicPortManager.updateOrCreate({ id: publicPort.id }, publicPort.toJSON(), transaction) - } -} - -async function createPortMapping (microservice, portMappingData, transaction) { - if (!microservice.iofogUuid) { - throw new Errors.ValidationError(AppHelper.formatMessage(ErrorMessages.REQUIRED_FOG_NODE)) - } - - const msPorts = await MicroservicePortManager.findOne({ - microserviceUuid: microservice.uuid, - [Op.or]: [] - }, transaction) - if (msPorts) { - throw new Errors.ValidationError(ErrorMessages.PORT_MAPPING_ALREADY_EXISTS) - } - - portMappingData.protocol = portMappingData.protocol || '' - - if (portMappingData.public) { - return _createPublicPortMapping(microservice, portMappingData, transaction) - } else { - return _createSimplePortMapping(microservice, portMappingData, transaction) - } -} - -async function _createOrUpdateProxyMicroservice (mapping, networkRouter, hostUuid, proxyCatalogId, transaction) { - const existingProxy = await MicroserviceManager.findOne({ catalogItemId: proxyCatalogId, iofogUuid: hostUuid }, transaction) - if (existingProxy) { - const config = JSON.parse(existingProxy.config || '{}') - config.mappings = (config.mappings || []).concat(mapping) - existingProxy.config = JSON.stringify(config) - await MicroserviceManager.updateIfChanged({ uuid: existingProxy.uuid }, { config: JSON.stringify(config) }, transaction) - await ChangeTrackingService.update(hostUuid, ChangeTrackingService.events.microserviceConfig, transaction) - return existingProxy - } - - const proxyMicroserviceData = { - uuid: AppHelper.generateRandomString(32), - name: `proxy-${hostUuid.toLowerCase()}`, - config: JSON.stringify({ - mappings: [mapping], - networkRouter - }), - catalogItemId: proxyCatalogId, - iofogUuid: hostUuid, - rootHostAccess: true, - registryId: 1, - logSize: MICROSERVICE_DEFAULT_LOG_SIZE, - configLastUpdated: Date.now() - } - const application = await ApplicationManager.findOne({ name: `system-${hostUuid.toLowerCase()}` }, transaction) - proxyMicroserviceData.applicationId = application.id - const res = await MicroserviceManager.create(proxyMicroserviceData, transaction) - await MicroserviceStatusManager.create({ microserviceUuid: proxyMicroserviceData.uuid }, transaction) - await ChangeTrackingService.update(hostUuid, ChangeTrackingService.events.microserviceCommon, transaction) - return res -} - -async function _createPublicPortMapping (microservice, portMappingData, transaction) { - const isTcp = portMappingData.public.protocol ? portMappingData.public.protocol.toLowerCase() === 'tcp' : false - const isUdp = portMappingData.protocol.toLowerCase() === 'udp' - const localAgent = portMappingData.localAgent // This is populated by validating the ports - const localAgentsRouter = localAgent.routerId ? await RouterManager.findOne({ id: localAgent.routerId }, transaction) : await RouterManager.findOne({ iofogUuid: localAgent.uuid }, transaction) - const localNetworkRouter = { - // host: localAgentsRouter.host, - host: 'localhost', - port: localAgentsRouter.messagingPort - } - - // create proxy microservices - const queueName = AppHelper.generateRandomString(32) - const proxyCatalog = await CatalogService.getProxyCatalogItem(transaction) - const localMapping = `amqp:${queueName}=>${isTcp ? 'tcp' : 'http'}:${portMappingData.external}` - const remoteMapping = `${isTcp ? 'tcp' : 'http'}:${portMappingData.publicPort}=>amqp:${queueName}` - - const localProxy = !portMappingData.public.disabled - ? await _createOrUpdateProxyMicroservice( - localMapping, - localNetworkRouter, - microservice.iofogUuid, - proxyCatalog.id, - transaction) - : null - - let remoteProxy - if (portMappingData.publicHost) { - const hostRouter = portMappingData.publicHost.routerId ? await RouterManager.findOne({ id: portMappingData.publicHost.routerId }, transaction) : await RouterManager.findOne({ iofogUuid: portMappingData.publicHost.uuid }, transaction) - const remoteNetworkRouter = { - // host: hostRouter.host, - host: 'localhost', - port: hostRouter.messagingPort - } - - remoteProxy = !portMappingData.public.disabled - ? await _createOrUpdateProxyMicroservice( - remoteMapping, - remoteNetworkRouter, - portMappingData.publicHost.uuid, - proxyCatalog.id, - transaction) - : null - } - - const mappingData = { - isPublic: true, - isProxy: false, - portInternal: portMappingData.internal, - portExternal: portMappingData.external, - isUdp, - microserviceUuid: microservice.uuid - } - const port = await MicroservicePortManager.create(mappingData, transaction) - const schemes = portMappingData.public && portMappingData.public.schemes - - const publicPort = { - portId: port.id, - hostId: portMappingData.publicHost ? portMappingData.publicHost.uuid : null, - localProxyId: localProxy.uuid, - remoteProxyId: portMappingData.publicHost ? remoteProxy.uuid : null, - publicPort: portMappingData.publicPort, - queueName, - schemes: JSON.stringify(schemes), - isTcp - } - await MicroservicePublicPortManager.create(publicPort, transaction) - - // Look for related extraHosts to update - const relatedExtraHosts = await MicroserviceExtraHostManager.findAll({ microserviceUuid: microservice.uuid, publicPort: publicPort.publicPort }, transaction) - for (const extraHost of relatedExtraHosts) { - extraHost.targetFogUuid = publicPort.hostId - extraHost.value = portMappingData.publicHost.host - await extraHost.save() - await MicroserviceExtraHostManager.updateOriginMicroserviceChangeTracking(extraHost, transaction) - } -} - -async function _deletePortMapping (microservice, portMapping, transaction) { - if (portMapping.isPublic) { - await _deletePublicPortMapping(microservice, portMapping, transaction) - } else { - await _deleteSimplePortMapping(microservice, portMapping, transaction) - } -} - -async function _updateOrDeleteProxyMicroservice (proxyId, proxyMapping, transaction) { - const proxy = await MicroserviceManager.findOne({ uuid: proxyId }, transaction) - if (!proxy) { - return - } - - const config = JSON.parse(proxy.config || '{}') - config.mappings = (config.mappings || []).filter(mapping => mapping !== proxyMapping) - if (config.mappings.length === 0) { - await MicroserviceManager.delete({ uuid: proxy.uuid }, transaction) - await ChangeTrackingService.update(proxy.iofogUuid, ChangeTrackingService.events.microserviceConfig, transaction) - } else { - await MicroserviceManager.updateIfChanged({ uuid: proxy.uuid }, { config: JSON.stringify(config) }, transaction) - await ChangeTrackingService.update(proxy.iofogUuid, ChangeTrackingService.events.microserviceCommon, transaction) - } -} - -async function _deletePublicPortMapping (microservice, portMapping, transaction) { - const publicPort = await portMapping.getPublicPort() - if (publicPort) { - const protocol = publicPort.isTcp ? 'tcp' : 'http' - const localMapping = `amqp:${publicPort.queueName}=>${protocol}:${portMapping.portExternal}` - const remoteMapping = `${protocol}:${publicPort.publicPort}=>amqp:${publicPort.queueName}` - - await _updateOrDeleteProxyMicroservice(publicPort.localProxyId, localMapping, transaction) - await _updateOrDeleteProxyMicroservice(publicPort.remoteProxyId, remoteMapping, transaction) - } - - await MicroservicePortManager.delete({ id: portMapping.id }, transaction) -} - -async function _createSimplePortMapping (microservice, portMappingData, transaction) { - // create port mapping - const mappingData = { - isPublic: false, - isProxy: false, - portInternal: portMappingData.internal, - portExternal: portMappingData.external, - isUdp: portMappingData.protocol.toLowerCase() === 'udp', - microserviceUuid: microservice.uuid - } - - await MicroservicePortManager.create(mappingData, transaction) - await switchOnUpdateFlagsForMicroservicesForPortMapping(microservice, false, transaction) -} - -async function _deleteSimplePortMapping (microservice, msPorts, transaction) { - await MicroservicePortManager.delete({ id: msPorts.id }, transaction) - - const updateRebuildMs = { - rebuild: true - } - await MicroserviceManager.update({ uuid: microservice.uuid }, updateRebuildMs, transaction) - await ChangeTrackingService.update(microservice.iofogUuid, ChangeTrackingService.events.microserviceCommon, transaction) -} - -async function _buildPortsList (portsPairs, transaction) { - const res = [] - for (const ports of portsPairs) { - const portMappingResponseData = { - internal: ports.portInternal, - external: ports.portExternal, - protocol: ports.isUdp ? 'udp' : 'tcp' - } - await buildPublicPortMapping(ports, portMappingResponseData, transaction) - res.push(portMappingResponseData) - } - return res -} - -function _buildLink (protocol, host, port) { - return `${protocol || 'http'}://${host}:${port}` -} - -async function buildPublicPortMapping (pm, mapping, transaction) { - if (!pm.isPublic) { - return - } - - const publicPortMapping = await pm.getPublicPort() - if (!publicPortMapping) { - return - } - - const port = publicPortMapping.publicPort - const hostRouter = publicPortMapping.hostId ? await RouterManager.findOne({ iofogUuid: publicPortMapping.hostId }, transaction) : { host: lget(await ConfigManager.findOne({ key: DEFAULT_PROXY_HOST }, transaction), 'value', 'undefined-proxy-host') } - const hostFog = publicPortMapping.hostId ? await FogManager.findOne({ uuid: publicPortMapping.hostId }, transaction) : { uuid: DEFAULT_ROUTER_NAME } - const schemes = JSON.parse(publicPortMapping.schemes) - mapping.public = { - links: schemes.map(s => _buildLink(s, hostRouter.host, port)), - protocol: publicPortMapping.protocol, - schemes, - enabled: !!publicPortMapping.localProxyId - } - mapping.public.router = { - port, - host: hostFog.isSystem ? DEFAULT_ROUTER_NAME : hostFog.uuid - } -} - -async function switchOnUpdateFlagsForMicroservicesForPortMapping (microservice, isPublic, transaction) { - const updateRebuildMs = { - rebuild: true - } - await MicroserviceManager.update({ uuid: microservice.uuid }, updateRebuildMs, transaction) - - if (isPublic) { - await ChangeTrackingService.update(microservice.iofogUuid, ChangeTrackingService.events.microserviceFull, transaction) - } else { - await ChangeTrackingService.update(microservice.iofogUuid, ChangeTrackingService.events.microserviceConfig, transaction) - } -} - -async function listPortMappings (microserviceUuid, isCLI, transaction) { - const where = isCLI - ? { uuid: microserviceUuid } - : { uuid: microserviceUuid } - const microservice = await MicroserviceManager.findOne(where, transaction) - if (!microservice) { - throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_UUID, microserviceUuid)) - } - - const portsPairs = await MicroservicePortManager.findAll({ microserviceUuid }, transaction) - return _buildPortsList(portsPairs, transaction) -} - -async function deletePortMapping (microserviceUuid, internalPort, isCLI, transaction) { - const where = isCLI - ? { uuid: microserviceUuid } - : { uuid: microserviceUuid } - - const microservice = await MicroserviceManager.findMicroserviceOnGet(where, transaction) - if (!microservice) { - throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_UUID, microserviceUuid)) - } - - if (!internalPort) { - throw new Errors.ValidationError(ErrorMessages.PORT_MAPPING_INTERNAL_PORT_NOT_PROVIDED) - } - - const msPorts = await MicroservicePortManager.findOne({ - microserviceUuid: microservice.uuid, - portInternal: internalPort - }, transaction) - if (!msPorts) { - throw new Errors.NotFoundError('port mapping not exists') - } - - await _deletePortMapping(microservice, msPorts, transaction) -} - -async function deleteSystemPortMapping (microserviceUuid, internalPort, isCLI, transaction) { - const where = isCLI - ? { uuid: microserviceUuid } - : { uuid: microserviceUuid } - - const microservice = await MicroserviceManager.findOne(where, transaction) - if (!microservice) { - throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_UUID, microserviceUuid)) - } - - if (!internalPort) { - throw new Errors.ValidationError(ErrorMessages.PORT_MAPPING_INTERNAL_PORT_NOT_PROVIDED) - } - - const msPorts = await MicroservicePortManager.findOne({ - microserviceUuid: microservice.uuid, - portInternal: internalPort - }, transaction) - if (!msPorts) { - throw new Errors.NotFoundError('port mapping not exists') - } - - await _deletePortMapping(microservice, msPorts, transaction) -} - -async function deletePortMappings (microservice, transaction) { - const portMappings = await MicroservicePortManager.findAll({ microserviceUuid: microservice.uuid }, transaction) - for (const ports of portMappings) { - await _deletePortMapping(microservice, ports, transaction) - } -} - -async function getPortMappings (microserviceUuid, transaction) { - return MicroservicePortManager.findAll({ microserviceUuid }, transaction) -} - -function listAllPublicPorts (transaction) { - return MicroservicePortManager.findAllPublicPorts(transaction) -} - -module.exports = { - validatePublicPortAppHostTemplate, - validatePortMappings, - validatePortMapping, - movePublicPortsToNewFog, - switchOnUpdateFlagsForMicroservicesForPortMapping, - createPortMapping, - buildPublicPortMapping, - listPortMappings, - deletePortMapping, - deleteSystemPortMapping, - deletePortMappings, - getPortMappings, - listAllPublicPorts -} diff --git a/src/services/microservices-service.js b/src/services/microservices-service.js index be84fcda..1214d170 100644 --- a/src/services/microservices-service.js +++ b/src/services/microservices-service.js @@ -314,6 +314,10 @@ async function createMicroserviceEndPoint (microserviceData, isCLI, transaction) _validateImagesAgainstCatalog(catalogItem, microserviceData.images || []) microserviceData.images = catalogItem.images _validateImageFogType(microserviceData, fog, catalogItem.images) + // use catalog item's registryId if it is set + if (catalogItem.registryId) { + microserviceData.registryId = catalogItem.registryId + } } else { _validateImageFogType(microserviceData, fog, microserviceData.images) } @@ -519,7 +523,8 @@ async function updateSystemMicroserviceEndPoint (microserviceUuid, microserviceD catalogItemId: microserviceData.catalogItemId, rebuild: microserviceData.rebuild, iofogUuid: newFog.uuid, - rootHostAccess: microserviceData.rootHostAccess, + hostNetworkMode: microserviceData.hostNetworkMode, + isPrivileged: microserviceData.isPrivileged, cpuSetCpus: microserviceData.cpuSetCpus, memoryLimit: microserviceData.memoryLimit, schedule: microserviceData.schedule, @@ -600,6 +605,11 @@ async function updateSystemMicroserviceEndPoint (microserviceUuid, microserviceD await _deleteImages(microserviceUuid, transaction) microserviceDataUpdate.registryId = catalogItem.registryId || 1 } + } else { + // use catalog item's registryId if it is set + if (catalogItem.registryId) { + microserviceDataUpdate.registryId = catalogItem.registryId + } } } else if (!microservice.catalogItemId && microserviceDataUpdate.images && microserviceDataUpdate.images.length === 0) { // No catalog, and no image @@ -640,7 +650,8 @@ async function updateSystemMicroserviceEndPoint (microserviceUuid, microserviceD // Set rebuild flag if needed microserviceDataUpdate.rebuild = microserviceDataUpdate.rebuild || !!( - (microserviceDataUpdate.rootHostAccess !== undefined && microservice.rootHostAccess !== microserviceDataUpdate.rootHostAccess) || + (microserviceDataUpdate.hostNetworkMode !== undefined && microservice.hostNetworkMode !== microserviceDataUpdate.hostNetworkMode) || + (microserviceDataUpdate.isPrivileged !== undefined && microservice.isPrivileged !== microserviceDataUpdate.isPrivileged) || microserviceDataUpdate.pidMode || microserviceDataUpdate.ipcMode || microserviceDataUpdate.cpuSetCpus || @@ -762,7 +773,8 @@ async function updateMicroserviceEndPoint (microserviceUuid, microserviceData, i catalogItemId: microserviceData.catalogItemId, rebuild: microserviceData.rebuild, iofogUuid: newFog.uuid, - rootHostAccess: microserviceData.rootHostAccess, + hostNetworkMode: microserviceData.hostNetworkMode, + isPrivileged: microserviceData.isPrivileged, cpuSetCpus: microserviceData.cpuSetCpus, memoryLimit: microserviceData.memoryLimit, schedule: microserviceData.schedule, @@ -847,6 +859,11 @@ async function updateMicroserviceEndPoint (microserviceUuid, microserviceData, i await _deleteImages(microserviceUuid, transaction) microserviceDataUpdate.registryId = catalogItem.registryId || 1 } + } else { + // use catalog item's registryId if it is set + if (catalogItem.registryId) { + microserviceDataUpdate.registryId = catalogItem.registryId + } } } else if (!microservice.catalogItemId && microserviceDataUpdate.images && microserviceDataUpdate.images.length === 0) { // No catalog, and no image @@ -887,7 +904,8 @@ async function updateMicroserviceEndPoint (microserviceUuid, microserviceData, i // Set rebuild flag if needed microserviceDataUpdate.rebuild = microserviceDataUpdate.rebuild || !!( - (microserviceDataUpdate.rootHostAccess !== undefined && microservice.rootHostAccess !== microserviceDataUpdate.rootHostAccess) || + (microserviceDataUpdate.hostNetworkMode !== undefined && microservice.hostNetworkMode !== microserviceDataUpdate.hostNetworkMode) || + (microserviceDataUpdate.isPrivileged !== undefined && microservice.isPrivileged !== microserviceDataUpdate.isPrivileged) || microserviceDataUpdate.pidMode || microserviceDataUpdate.ipcMode || microserviceDataUpdate.cpuSetCpus || @@ -1240,13 +1258,12 @@ async function deleteMicroserviceEndPoint (microserviceUuid, microserviceData, i throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.SYSTEM_MICROSERVICE_DELETE, microserviceUuid)) } - await deleteMicroserviceWithRoutesAndPortMappings(microservice, transaction) - const existingService = await ServiceManager.findOne({ type: `microservice`, resource: microservice.uuid }, transaction) if (existingService) { logger.info(`Deleting service ${existingService.name}`) await ServiceServices.deleteServiceEndpoint(existingService.name, transaction) } + await deleteMicroserviceWithRoutesAndPortMappings(microservice, transaction) await _updateChangeTracking(false, microservice.iofogUuid, transaction) } @@ -1726,7 +1743,8 @@ async function _createMicroservice (microserviceData, isCLI, transaction) { annotations: annotations, catalogItemId: microserviceData.catalogItemId, iofogUuid: microserviceData.iofogUuid, - rootHostAccess: microserviceData.rootHostAccess, + hostNetworkMode: microserviceData.hostNetworkMode, + isPrivileged: microserviceData.isPrivileged, cpuSetCpus: microserviceData.cpuSetCpus, memoryLimit: microserviceData.memoryLimit, pidMode: microserviceData.pidMode, diff --git a/src/services/registry-service.js b/src/services/registry-service.js index de0a8ead..62955855 100644 --- a/src/services/registry-service.js +++ b/src/services/registry-service.js @@ -18,24 +18,20 @@ const ErrorMessages = require('../helpers/error-messages') const ChangeTrackingService = require('./change-tracking-service') const TransactionDecorator = require('../decorators/transaction-decorator') const FogManager = require('../data/managers/iofog-manager') -const Sequelize = require('sequelize') -const Op = Sequelize.Op +const MicroserviceManager = require('../data/managers/microservice-manager') +// const Sequelize = require('sequelize') +// const Op = Sequelize.Op const AppHelper = require('../helpers/app-helper') const createRegistry = async function (registry, transaction) { await Validator.validate(registry, Validator.schemas.registryCreate) - if (registry.requiresCert && registry.certificate === undefined) { - throw new Errors.ValidationError(ErrorMessages.CERT_PROPERTY_REQUIRED) - } let registryCreate = { url: registry.url, username: registry.username, password: registry.password, isPublic: registry.isPublic, - userEmail: registry.email, - requiresCert: registry.requiresCert, - certificate: registry.certificate + userEmail: registry.email } registryCreate = AppHelper.deleteUndefinedFields(registryCreate) @@ -52,14 +48,7 @@ const createRegistry = async function (registry, transaction) { const findRegistries = async function (isCLI, transaction) { const queryRegistry = isCLI ? {} - : { - [Op.or]: - [ - { - isPublic: true - } - ] - } + : {} const registries = await RegistryManager.findAllWithAttributes(queryRegistry, { exclude: ['password'] }, transaction) return { @@ -72,21 +61,31 @@ const deleteRegistry = async function (registryData, isCLI, transaction) { const queryData = isCLI ? { id: registryData.id } : { id: registryData.id } + // Convert registryId to number to handle string IDs from URL parameters + const id = parseInt(registryData.id, 10) + if (id === 1 || id === 2) { + throw new Errors.ValidationError(ErrorMessages.REGISTRY_IS_SYSTEM) + } const registry = await RegistryManager.findOne(queryData, transaction) if (!registry) { throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_REGISTRY_ID, registryData.id)) } - await RegistryManager.delete(queryData, transaction) - await _updateChangeTracking(transaction) + const microservices = await MicroserviceManager.findAllWithStatuses({ registryId: registryData.id }, transaction) + if (microservices.length > 0) { + throw new Errors.ValidationError(ErrorMessages.REGISTRY_IS_IN_USE) + } else { + await RegistryManager.delete(queryData, transaction) + await _updateChangeTracking(transaction) + } } const updateRegistry = async function (registry, registryId, isCLI, transaction) { await Validator.validate(registry, Validator.schemas.registryUpdate) - - if (registry.requiresCert && registry.certificate === undefined) { - throw new Errors.ValidationError(ErrorMessages.CERT_PROPERTY_REQUIRED) + // Convert registryId to number to handle string IDs from URL parameters + const id = parseInt(registryId, 10) + if (id === 1 || id === 2) { + throw new Errors.ValidationError(ErrorMessages.REGISTRY_IS_SYSTEM) } - const existingRegistry = await RegistryManager.findOne({ id: registryId }, transaction) @@ -100,9 +99,7 @@ const updateRegistry = async function (registry, registryId, isCLI, transaction) username: registry.username, password: registry.password, isPublic: registry.isPublic, - userEmail: registry.email, - requiresCert: registry.requiresCert, - certificate: registry.certificate + userEmail: registry.email } registryUpdate = AppHelper.deleteUndefinedFields(registryUpdate) @@ -116,12 +113,19 @@ const updateRegistry = async function (registry, registryId, isCLI, transaction) } await RegistryManager.update(where, registryUpdate, transaction) + const microservices = await MicroserviceManager.findAllWithStatuses({ registryId: registryId }, transaction) + if (microservices.length > 0) { + for (const ms of microservices) { + await MicroserviceManager.updateAndFind({ uuid: ms.uuid }, { rebuild: true }, transaction) + await ChangeTrackingService.update(ms.iofogUuid, ChangeTrackingService.events.microserviceCommon, transaction) + } + } await _updateChangeTracking(transaction) } const _updateChangeTracking = async function (transaction) { - const fogs = await FogManager.findAll(transaction) + const fogs = await FogManager.findAll({}, transaction) for (const fog of fogs) { await ChangeTrackingService.update(fog.uuid, ChangeTrackingService.events.registries, transaction) } diff --git a/src/services/router-service.js b/src/services/router-service.js index 8286c138..c384e6d7 100644 --- a/src/services/router-service.js +++ b/src/services/router-service.js @@ -31,6 +31,7 @@ const ldifferenceWith = require('lodash/differenceWith') const constants = require('../helpers/constants') const MicroserviceEnvManager = require('../data/managers/microservice-env-manager') const SecretManager = require('../data/managers/secret-manager') +const FogManager = require('../data/managers/iofog-manager') const SITE_CONFIG_VERSION = 'pot' const SITE_CONFIG_NAMESPACE = 'datasance' @@ -42,7 +43,29 @@ async function validateAndReturnUpstreamRouters (upstreamRouterIds, isSystemFog, if (isSystemFog) { return [] } throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_ROUTER, Constants.DEFAULT_ROUTER_NAME)) } - return [defaultRouter] + + // Get all system fogs + const allSystemFogs = await FogManager.findAll({ isSystem: true }, transaction) + + // Get routers for each system fog + const systemFogRouters = [] + for (const systemFog of allSystemFogs) { + const systemFogRouter = await RouterManager.findOne({ iofogUuid: systemFog.uuid }, transaction) + if (systemFogRouter) { + systemFogRouters.push(systemFogRouter) + } + } + + // Combine default router with system fog routers, removing duplicates + const combinedRouters = [defaultRouter] + for (const systemFogRouter of systemFogRouters) { + // Check if this system fog router is not the same as the default router + if (systemFogRouter.id !== defaultRouter.id) { + combinedRouters.push(systemFogRouter) + } + } + + return combinedRouters } const upstreamRouters = [] @@ -295,7 +318,7 @@ function _createRouterPorts (routerMicroserviceUuid, port, transaction) { async function _createRouterMicroservice (isEdge, uuid, microserviceConfig, transaction) { const routerCatalog = await CatalogService.getRouterCatalogItem(transaction) - + const hostNetworkMode = !isEdge const routerApplicationData = { name: `system-${uuid.toLowerCase()}`, isActivated: true, @@ -307,7 +330,8 @@ async function _createRouterMicroservice (isEdge, uuid, microserviceConfig, tran config: JSON.stringify(microserviceConfig), catalogItemId: routerCatalog.id, iofogUuid: uuid, - rootHostAccess: false, + hostNetworkMode: hostNetworkMode, + isPrivileged: false, logSize: constants.MICROSERVICE_DEFAULT_LOG_SIZE, schedule: 0, configLastUpdated: Date.now(), diff --git a/src/services/secret-service.js b/src/services/secret-service.js index a51e11a6..c788d255 100644 --- a/src/services/secret-service.js +++ b/src/services/secret-service.js @@ -13,12 +13,16 @@ const TransactionDecorator = require('../decorators/transaction-decorator') const SecretManager = require('../data/managers/secret-manager') +const MicroserviceManager = require('../data/managers/microservice-manager') +const MicroserviceEnvManager = require('../data/managers/microservice-env-manager') +const ChangeTrackingService = require('./change-tracking-service') const AppHelper = require('../helpers/app-helper') const Errors = require('../helpers/errors') const ErrorMessages = require('../helpers/error-messages') const Validator = require('../schemas/index') const VolumeMountService = require('./volume-mount-service') const VolumeMountingManager = require('../data/managers/volume-mounting-manager') +const CertificateManager = require('../data/managers/certificate-manager') function validateBase64 (value) { try { @@ -82,6 +86,7 @@ async function updateSecretEndpoint (secretName, secretData, transaction) { const secret = await SecretManager.updateSecret(secretName, secretData.data, transaction) await _updateChangeTrackingForFogs(secretName, transaction) + await _updateMicroservicesUsingSecret(secretName, transaction) return { id: secret.id, name: secret.name, @@ -126,10 +131,38 @@ async function deleteSecretEndpoint (secretName, transaction) { throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.SECRET_NOT_FOUND, secretName)) } - await SecretManager.deleteSecret(secretName, transaction) + if (existingSecret.type === 'tls') { + const certificate = await CertificateManager.findCertificateByName(secretName, transaction) + if (certificate) { + if (certificate.isCA) { + // Check if this CA has signed certificates + const signedCerts = await CertificateManager.findCertificatesByCA(certificate.id, transaction) + if (signedCerts.length > 0) { + throw new Errors.ValidationError(`Cannot delete CA that has signed certificates. Please delete the following certificates first: ${signedCerts.map(cert => cert.name).join(', ')}`) + } + await CertificateManager.deleteCertificate(certificate.name, transaction) + await _deleteVolumeMountsUsingSecret(secretName, transaction) + } else { + await CertificateManager.deleteCertificate(certificate.name, transaction) + await _deleteVolumeMountsUsingSecret(secretName, transaction) + } + } + } else { + await SecretManager.deleteSecret(secretName, transaction) + await _deleteVolumeMountsUsingSecret(secretName, transaction) + } return {} } +async function _deleteVolumeMountsUsingSecret (secretName, transaction) { + const volumeMounts = await VolumeMountingManager.findAll({ secretName: secretName }, transaction) + if (volumeMounts.length > 0) { + for (const volumeMount of volumeMounts) { + await VolumeMountService.deleteVolumeMountEndpoint(volumeMount.name, transaction) + } + } +} + async function _updateChangeTrackingForFogs (secretName, transaction) { const secretVolumeMounts = await VolumeMountingManager.findAll({ secretName: secretName }, transaction) if (secretVolumeMounts.length > 0) { @@ -143,6 +176,69 @@ async function _updateChangeTrackingForFogs (secretName, transaction) { } } +async function _updateMicroservicesUsingSecret (secretName, transaction) { + // Find all microservice environment variables that use this secret + const envVars = await MicroserviceEnvManager.findAll({ + valueFromSecret: { [require('sequelize').Op.like]: `${secretName}/%` } + }, transaction) + + if (envVars.length === 0) { + return + } + + // Get the updated secret data + const secret = await SecretManager.getSecret(secretName, transaction) + if (!secret) { + return + } + + // Group environment variables by microservice UUID + const microserviceEnvMap = new Map() + for (const envVar of envVars) { + if (!microserviceEnvMap.has(envVar.microserviceUuid)) { + microserviceEnvMap.set(envVar.microserviceUuid, []) + } + microserviceEnvMap.get(envVar.microserviceUuid).push(envVar) + } + + // Update each microservice's environment variables and change tracking + for (const [microserviceUuid, envVars] of microserviceEnvMap) { + // Get the microservice to access its iofogUuid + const microservice = await MicroserviceManager.findOne({ uuid: microserviceUuid }, transaction) + if (!microservice) { + continue + } + + // Update each environment variable with the new secret data + for (const envVar of envVars) { + const [secretNameFromRef, dataKey] = envVar.valueFromSecret.split('/') + if (secretNameFromRef === secretName && secret.data[dataKey]) { + let newValue = secret.data[dataKey] + + // If it's a TLS secret, decode the base64 value + if (secret.type === 'tls') { + try { + newValue = Buffer.from(secret.data[dataKey], 'base64').toString('utf-8') + } catch (error) { + // Skip this environment variable if base64 decoding fails + continue + } + } + + // Update the environment variable value with the new secret data + await MicroserviceEnvManager.update( + { id: envVar.id }, + { value: newValue }, + transaction + ) + } + } + + // Update change tracking for the microservice's fog node + await ChangeTrackingService.update(microservice.iofogUuid, ChangeTrackingService.events.microserviceCommon, transaction) + } +} + module.exports = { createSecretEndpoint: TransactionDecorator.generateTransaction(createSecretEndpoint), updateSecretEndpoint: TransactionDecorator.generateTransaction(updateSecretEndpoint), diff --git a/src/services/services-service.js b/src/services/services-service.js index be2982ab..2b2c0b59 100644 --- a/src/services/services-service.js +++ b/src/services/services-service.js @@ -257,7 +257,7 @@ async function _determineConnectorHost (serviceConfig, transaction) { switch (serviceConfig.type.toLowerCase()) { case 'microservice': const microservice = await MicroserviceManager.findOne({ uuid: serviceConfig.resource }, transaction) - if (microservice.rootHostAccess) { + if (microservice.hostNetworkMode) { return 'iofog' } else { return `iofog_${serviceConfig.resource}` @@ -462,14 +462,20 @@ async function _addTcpListener (serviceConfig, transaction) { // If not in K8s environment, always include default router if (!isK8s) { - const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) - if (!defaultRouter) { - logger.error('Default router not found') - throw new Errors.NotFoundError('Default router not found') - } - // Add default router if not already in the list - if (!fogNodeUuids.includes(defaultRouter.iofogUuid)) { - fogNodeUuids.push(defaultRouter.iofogUuid) + if (serviceConfig.defaultBridge === 'default-router') { + const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) + if (!defaultRouter) { + logger.error('Default router not found') + throw new Errors.NotFoundError('Default router not found') + } + // Add default router if not already in the list + if (!fogNodeUuids.includes(defaultRouter.iofogUuid)) { + fogNodeUuids.push(defaultRouter.iofogUuid) + } + } else { + if (!fogNodeUuids.includes(serviceConfig.defaultBridge)) { + fogNodeUuids.push(serviceConfig.defaultBridge) + } } } // else if (!fogNodeUuids || fogNodeUuids.length === 0) { @@ -950,6 +956,23 @@ async function createServiceEndpoint (serviceData, transaction) { // Set provisioning fields serviceData.provisioningStatus = 'pending' serviceData.provisioningError = null + if (!isK8s) { + if (serviceData.defaultBridge === 'default-router') { + const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) + if (!defaultRouter) { + throw new Errors.NotFoundError('Default router not found') + } + serviceData.serviceEndpoint = defaultRouter.host + serviceData.servicePort = serviceData.bridgePort + } else { + const router = await RouterManager.findOne({ iofogUuid: serviceData.defaultBridge }, transaction) + if (!router) { + throw new Errors.NotFoundError('Router not found') + } + serviceData.serviceEndpoint = router.host + serviceData.servicePort = serviceData.bridgePort + } + } // 7. Create service in database first logger.debug('Creating service in database') @@ -1008,6 +1031,10 @@ async function updateServiceEndpoint (serviceName, serviceData, transaction) { throw new Errors.ValidationError('Changing service type is not allowed. Please delete the service and create a new one with the desired type.') } + if (serviceData.defaultBridge && serviceData.defaultBridge !== existingService.defaultBridge) { + throw new Errors.ValidationError('Changing default bridge is not allowed. Please delete the service and create a new one with the desired default bridge.') + } + // 4. Check K8s environment if type is k8s const isK8s = await checkKubernetesEnvironment() if (existingService.type === 'k8s' && !isK8s) { @@ -1040,6 +1067,24 @@ async function updateServiceEndpoint (serviceName, serviceData, transaction) { serviceData.provisioningStatus = 'pending' serviceData.provisioningError = null + if (!isK8s) { + if (serviceData.defaultBridge === 'default-router') { + const defaultRouter = await RouterManager.findOne({ isDefault: true }, transaction) + if (!defaultRouter) { + throw new Errors.NotFoundError('Default router not found') + } + serviceData.serviceEndpoint = defaultRouter.host + serviceData.servicePort = serviceData.bridgePort + } else { + const router = await RouterManager.findOne({ iofogUuid: serviceData.defaultBridge }, transaction) + if (!router) { + throw new Errors.NotFoundError('Router not found') + } + serviceData.serviceEndpoint = router.host + serviceData.servicePort = serviceData.bridgePort + } + } + // 8. Update service in database const updatedService = await ServiceManager.update( { name: serviceName }, diff --git a/src/services/yaml-parser-service.js b/src/services/yaml-parser-service.js index adc8d94c..084f2f3e 100644 --- a/src/services/yaml-parser-service.js +++ b/src/services/yaml-parser-service.js @@ -333,7 +333,8 @@ const parseMicroserviceYAML = async (microservice) => { agentName: lget(microservice, 'agent.name'), registryId, ...container, - rootHostAccess: lget(microservice, 'container.rootHostAccess', false), + hostNetworkMode: lget(microservice, 'container.hostNetworkMode', false), + isPrivileged: lget(microservice, 'container.isPrivileged', false), pidMode: lget(microservice, 'container.pidMode', ''), ipcMode: lget(microservice, 'container.ipcMode', ''), cpuSetCpus: lget(microservice, 'container.cpuSetCpus', ''),