diff --git a/Makefile b/Makefile index 14ddda41..9e540075 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,12 @@ NS?=openfaas build-gateway: (cd gateway; docker buildx build --platform linux/amd64 -t ${NS}/gateway:latest-dev .) + +# generate Go models from the OpenAPI spec using https://github.com/contiamo/openapi-generator-go +generate: + rm gateway/models/model_*.go || true + openapi-generator-go generate models -s api-docs/spec.openapi.yml -o gateway/models --package-name models + # .PHONY: test-ci # test-ci: # ./contrib/ci.sh diff --git a/api-docs/spec.openapi.yml b/api-docs/spec.openapi.yml new file mode 100644 index 00000000..1e251e4a --- /dev/null +++ b/api-docs/spec.openapi.yml @@ -0,0 +1,968 @@ +openapi: 3.0.1 +info: + title: OpenFaaS API Gateway + description: OpenFaaS API documentation + license: + name: MIT + version: 0.8.12 + contact: + name: OpenFaaS Ltd + url: https://www.openfaas.com/support/ +servers: +- url: "http://localhost:8080" + description: Local server +tags: + - name: internal + description: Internal use only + - name: system + description: System endpoints for managing functions and related objects + - name: function + description: Endpoints for invoking functions +paths: + "/healthz": + get: + summary: Healthcheck + operationId: healthcheck + description: Healthcheck for the gateway, indicates if the gateway is running and available + tags: + - internal + responses: + '200': + description: Healthy + '500': + description: Not healthy + "/metrics": + get: + summary: Prometheus metrics + operationId: metrics + description: Prometheus metrics for the gateway + tags: + - internal + responses: + '200': + description: Prometheus metrics in text format + "/system/info": + get: + operationId: GetSystemInfo + description: Get system provider information + summary: Get info such as provider version number and provider orchestrator + tags: + - system + responses: + '200': + description: Info result + content: + application/json: + schema: + "$ref": "#/components/schemas/GatewayInfo" + '500': + description: Internal Server Error + "/system/alert": + post: + operationId: ScaleAlert + description: Scale a function based on an alert + summary: | + Event-sink for AlertManager, for auto-scaling + + Internal use for AlertManager, requires valid AlertManager alert + JSON + tags: + - internal + requestBody: + description: Incoming alert + content: + application/json: + schema: + $ref: '#/components/schemas/PrometheusAlert' + required: false + responses: + '200': + description: Alert handled successfully + '500': + description: Internal error with swarm or request JSON invalid + "/system/functions": + get: + operationId: GetFunctions + description: Get a list of deployed functions + summary: 'Get a list of deployed functions with: stats and image digest' + tags: + - system + responses: + '200': + description: List of deployed functions. + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/FunctionStatus" + put: + operationId: UpdateFunction + description: update a function spec + summary: Update a function. + tags: + - system + requestBody: + description: Function to update + content: + application/json: + schema: + "$ref": "#/components/schemas/FunctionDeployment" + required: true + responses: + '200': + description: Accepted + '400': + description: Bad Request + '404': + description: Not Found + '500': + description: Internal Server Error + post: + operationId: DeployFunction + description: Deploy a new function. + summary: Deploy a new function. + tags: + - system + requestBody: + description: Function to deploy + content: + application/json: + schema: + "$ref": "#/components/schemas/FunctionDeployment" + required: true + responses: + '202': + description: Accepted + '400': + description: Bad Request + '500': + description: Internal Server Error + delete: + operationId: DeleteFunction + description: Remove a deployed function. + summary: Remove a deployed function. + tags: + - system + requestBody: + description: Function to delete + content: + application/json: + schema: + "$ref": "#/components/schemas/DeleteFunctionRequest" + required: true + responses: + '200': + description: OK + '400': + description: Bad Request + '404': + description: Not Found + '500': + description: Internal Server Error + "/system/scale-function/{functionName}": + post: + operationId: ScaleFunction + description: Scale a function + summary: Scale a function to a specific replica count + tags: + - system + parameters: + - name: functionName + in: path + description: Function name + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ScaleServiceRequest' + responses: + '200': + description: Scaling OK + '202': + description: Scaling OK + '404': + description: Function not found + '500': + description: Error scaling function + + "/system/function/{functionName}": + get: + operationId: GetFunctionStatus + description: Get the status of a function by name + tags: + - system + parameters: + - name: functionName + in: path + description: Function name + required: true + schema: + type: string + - name: namespace + in: query + description: Namespace of the function + required: false + schema: + type: string + responses: + '200': + description: Function Summary + content: + "*/*": + schema: + "$ref": "#/components/schemas/FunctionStatus" + '404': + description: Not Found + '500': + description: Internal Server Error + "/system/secrets": + get: + operationId: ListSecrets + description: Get a list of secret names and metadata from the provider + summary: Get a list of secret names and metadata from the provider + tags: + - system + responses: + '200': + description: List of submitted secrets. + content: + application/json: + schema: + "$ref": "#/components/schemas/SecretDescription" + put: + operationId: UpdateSecret + description: Update a secret. + summary: Update a secret, the value is replaced. + tags: + - system + requestBody: + description: Secret to update + content: + application/json: + schema: + "$ref": "#/components/schemas/Secret" + required: true + responses: + '200': + description: Ok + '400': + description: Bad Request + '404': + description: Not Found + '405': + description: Method Not Allowed. Secret update is not allowed in faas-swarm. + '500': + description: Internal Server Error + post: + operationId: CreateSecret + description: Create a new secret. + tags: + - system + requestBody: + description: A new secret to create + content: + application/json: + schema: + "$ref": "#/components/schemas/Secret" + required: true + responses: + '201': + description: Created + '400': + description: Bad Request + '500': + description: Internal Server Error + delete: + operationId: DeleteSecret + description: Remove a secret. + tags: + - system + requestBody: + description: Secret to delete + content: + application/json: + schema: + "$ref": "#/components/schemas/SecretDescription" + required: true + responses: + '204': + description: OK + '400': + description: Bad Request + '404': + description: Not Found + '500': + description: Internal Server Error + "/system/logs": + get: + operationId: GetFunctionLogs + description: Get a stream of the logs for a specific function + tags: + - system + parameters: + - name: name + in: query + description: Function name + required: true + schema: + type: string + - name: namespace + in: query + description: Namespace of the function + required: false + schema: + type: string + - name: instance + in: query + description: Instance of the function + required: false + schema: + type: string + - name: tail + in: query + description: Sets the maximum number of log messages to return, <=0 means + unlimited + schema: + type: integer + - name: follow + in: query + description: When true, the request will stream logs until the request timeout + schema: + type: boolean + - name: since + in: query + description: Only return logs after a specific date (RFC3339) + schema: + type: string + format: date-time + responses: + '200': + description: Newline delimited stream of log messages + content: + application/x-ndjson: + schema: + "$ref": "#/components/schemas/LogEntry" + '404': + description: Not Found + '500': + description: Internal Server Error + + "/async-function/{functionName}": + post: + operationId: InvokeAsync + description: Invoke a function asynchronously + summary: | + Invoke a function asynchronously in the default OpenFaaS namespace + + Any additional path segments and query parameters will be passed to the function as is. + + See https://docs.openfaas.com/reference/async/. + tags: + - function + parameters: + - name: functionName + in: path + description: Function name + required: true + schema: + type: string + requestBody: + description: "(Optional) data to pass to function" + content: + "*/*": + schema: + type: string + format: binary + example: '{"hello": "world"}' + required: false + responses: + '202': + description: Request accepted and queued + '404': + description: Not Found + '500': + description: Internal Server Error + + "/async-function/{functionName}.{namespace}": + post: + operationId: InvokeAsyncNamespaced + description: Invoke a function asynchronously in an OpenFaaS namespace. + summary: | + Invoke a function asynchronously in an OpenFaaS namespace. + + Any additional path segments and query parameters will be passed to the function as is. + + See https://docs.openfaas.com/reference/async/. + tags: + - function + parameters: + - name: functionName + in: path + description: Function name + required: true + schema: + type: string + - name: namespace + in: path + description: Namespace of the function + required: true + schema: + type: string + requestBody: + description: "(Optional) data to pass to function" + content: + "*/*": + schema: + type: string + format: binary + example: '{"hello": "world"}' + required: false + responses: + '202': + description: Request accepted and queued + '404': + description: Not Found + '500': + description: Internal Server Error + + "/function/{functionName}": + post: + operationId: InvokeFunction + description: Invoke a function in the default OpenFaaS namespace. + summary: | + Synchronously invoke a function defined in te default OpenFaaS namespace. + + Any additional path segments and query parameters will be passed to the function as is. + tags: + - function + parameters: + - name: functionName + in: path + description: Function name + required: true + schema: + type: string + requestBody: + description: "(Optional) data to pass to function" + content: + "*/*": + schema: + type: string + format: binary + example: '{"hello": "world"}' + required: false + responses: + '200': + description: Value returned from function + '404': + description: Not Found + '500': + description: Internal server error + + "/function/{functionName}.{namespace}": + post: + operationId: InvokeFunctionNamespaced + description: Invoke a function in an OpenFaaS namespace. + summary: | + Synchronously invoke a function defined in the specified namespace. + + Any additional path segments and query parameters will be passed to the function as is. + tags: + - function + parameters: + - name: functionName + in: path + description: Function name + required: true + schema: + type: string + - name: namespace + in: path + description: Namespace of the function + required: true + schema: + type: string + requestBody: + description: "(Optional) data to pass to function" + content: + "*/*": + schema: + type: string + format: binary + example: '{"hello": "world"}' + required: false + responses: + '200': + description: Value returned from function + '404': + description: Not Found + '500': + description: Internal server error +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + + schemas: + GatewayInfo: + required: + - provider + - version + - arch + type: object + properties: + provider: + nullable: true + allOf: + - $ref: "#/components/schemas/ProviderInfo" + version: + nullable: true + description: version of the gateway + allOf: + - $ref: "#/components/schemas/VersionInfo" + arch: + type: string + description: Platform architecture + example: x86_64 + VersionInfo: + type: object + required: + - sha + - release + properties: + commit_message: + type: string + example: Sample Message + sha: + type: string + example: 7108418d9dd6b329ddff40e7393b3166f8160a88 + release: + type: string + format: semver + example: 0.8.9 + ProviderInfo: + type: object + required: + - provider + - orchestration + - version + properties: + provider: + type: string + description: The orchestration provider / implementation + example: faas-netes + orchestration: + type: string + example: kubernetes + version: + description: The version of the provider + nullable: true + allOf: + - $ref: "#/components/schemas/VersionInfo" + + PrometheusAlert: + type: object + description: Prometheus alert produced by AlertManager. This is only a subset of the full alert payload. + required: + - status + - receiver + - alerts + properties: + status: + type: string + description: The status of the alert + example: resolved + receiver: + type: string + description: The name of the receiver + example: webhook + alerts: + type: array + description: The list of alerts + items: + $ref: "#/components/schemas/PrometheusInnerAlert" + example: + { + "receiver": "scale-up", + "status": "firing", + "alerts": [{ + "status": "firing", + "labels": { + "alertname": "APIHighInvocationRate", + "code": "200", + "function_name": "func_nodeinfo", + "instance": "gateway:8080", + "job": "gateway", + "monitor": "faas-monitor", + "service": "gateway", + "severity": "major", + "value": "8.998200359928017" + }, + "annotations": { + "description": "High invocation total on gateway:8080", + "summary": "High invocation total on gateway:8080" + }, + "startsAt": "2017-03-15T15:52:57.805Z", + "endsAt": "0001-01-01T00:00:00Z", + "generatorURL": "http://4156cb797423:9090/graph?g0.expr=rate%28gateway_function_invocation_total%5B10s%5D%29+%3E+5\u0026g0.tab=0" + }], + "groupLabels": { + "alertname": "APIHighInvocationRate", + "service": "gateway" + }, + "commonLabels": { + "alertname": "APIHighInvocationRate", + "code": "200", + "function_name": "func_nodeinfo", + "instance": "gateway:8080", + "job": "gateway", + "monitor": "faas-monitor", + "service": "gateway", + "severity": "major", + "value": "8.998200359928017" + }, + "commonAnnotations": { + "description": "High invocation total on gateway:8080", + "summary": "High invocation total on gateway:8080" + }, + "externalURL": "http://f054879d97db:9093", + "version": "3", + "groupKey": 18195285354214864953 + } + + PrometheusInnerAlert: + type: object + description: A single alert produced by Prometheus + required: + - status + - labels + properties: + status: + type: string + description: The status of the alert + example: resolved + labels: + $ref: "#/components/schemas/PrometheusInnerAlertLabel" + + PrometheusInnerAlertLabel: + type: object + description: A single label of a Prometheus alert + required: + - alertname + - function_name + properties: + alertname: + type: string + description: The name of the alert + function_name: + type: string + description: The name of the function + example: nodeinfo + + FunctionDeployment: + required: + - service + - image + type: object + properties: + service: + type: string + description: Name of deployed function + example: nodeinfo + image: + type: string + description: Docker image in accessible registry + example: functions/nodeinfo:latest + namespace: + type: string + description: Namespace to deploy function to. When omitted, the default namespace + is used, typically this is `openfaas-fn` but is configured by the provider. + example: openfaas-fn + envProcess: + type: string + description: | + Process for watchdog to fork, i.e. the command to start the function process. + + This value configures the `fprocess` env variable. + example: node main.js + constraints: + type: array + items: + type: string + description: Constraints are specific to OpenFaaS Provider + example: node.platform.os == linux + envVars: + type: object + additionalProperties: + type: string + description: Overrides to environmental variables + secrets: + type: array + items: + type: string + description: An array of names of secrets that are required to be loaded + from the Docker Swarm. + example: secret-name-1 + labels: + type: object + nullable: true + additionalProperties: + type: string + description: A map of labels for making scheduling or routing decisions + example: + foo: bar + annotations: + type: object + nullable: true + additionalProperties: + type: string + description: A map of annotations for management, orchestration, events + and build tasks + example: + topics: awesome-kafka-topic + foo: bar + limits: + nullable: true + allOf: + - $ref: "#/components/schemas/FunctionResources" + requests: + nullable: true + allOf: + - $ref: "#/components/schemas/FunctionResources" + readOnlyRootFilesystem: + type: boolean + description: Make the root filesystem of the function read-only + + # DEPRECATED FIELDS, these fields are ignored in all current providers + registryAuth: + type: string + description: | + Deprecated: Private registry base64-encoded basic auth (as present in ~/.docker/config.json) + + Use a Kubernetes Secret with registry-auth secret type to provide this value instead. + + This value is completely ignored. + example: dXNlcjpwYXNzd29yZA== + deprecated: true + network: + type: string + description: | + Deprecated: Network, usually func_functions for Swarm. + + This value is completely ignored. + deprecated: true + example: func_functions + + FunctionStatus: + type: object + required: + - name + - image + properties: + name: + type: string + description: The name of the function + example: nodeinfo + image: + type: string + description: The fully qualified docker image name of the function + example: functions/nodeinfo:latest + namespace: + type: string + description: The namespace of the function + example: openfaas-fn + envProcess: + type: string + description: Process for watchdog to fork + example: node main.js + envVars: + type: object + additionalProperties: + type: string + description: environment variables for the function runtime + constraints: + type: array + items: + type: string + description: Constraints are specific to OpenFaaS Provider + example: node.platform.os == linux + secrets: + type: array + items: + type: string + description: An array of names of secrets that are made available to the function + labels: + type: object + nullable: true + additionalProperties: + type: string + description: A map of labels for making scheduling or routing decisions + example: + foo: bar + annotations: + type: object + nullable: true + additionalProperties: + type: string + description: A map of annotations for management, orchestration, events + and build tasks + example: + topics: awesome-kafka-topic + foo: bar + limits: + nullable: true + allOf: + - $ref: "#/components/schemas/FunctionResources" + requests: + nullable: true + allOf: + - $ref: "#/components/schemas/FunctionResources" + readOnlyRootFilesystem: + type: boolean + description: removes write-access from the root filesystem mount-point. + invocationCount: + type: number + description: The amount of invocations for the specified function + format: integer + example: 1337 + replicas: + type: number + description: The current minimal ammount of replicas + format: integer + example: 2 + availableReplicas: + type: number + description: The current available amount of replicas + format: integer + example: 2 + createdAt: + type: string + description: | + is the time read back from the faas backend's + data store for when the function or its container was created. + format: date-time + usage: + nullable: true + allOf: + - $ref: "#/components/schemas/FunctionUsage" + + FunctionResources: + type: object + properties: + memory: + type: string + description: The amount of memory that is allocated for the function + example: 128M + cpu: + type: string + description: The amount of cpu that is allocated for the function + example: '0.01' + + FunctionUsage: + type: object + properties: + cpu: + type: number + description: | + is the increase in CPU usage since the last measurement + equivalent to Kubernetes' concept of millicores. + format: double + example: 0.01 + totalMemoryBytes: + type: number + description: is the total memory usage in bytes. + format: double + example: 1337 + + DeleteFunctionRequest: + required: + - functionName + type: object + properties: + functionName: + type: string + description: Name of deployed function + example: nodeinfo + + ScaleServiceRequest: + required: + - serviceName + - replicas + type: object + properties: + serviceName: + type: string + description: Name of deployed function + example: nodeinfo + replicas: + type: integer + format: int64 + minimum: 0 + description: Number of replicas to scale to + example: 2 + + SecretDescription: + required: + - name + type: object + properties: + name: + type: string + description: Name of secret + example: aws-key + namespace: + type: string + description: Namespace of secret + example: openfaas-fn + SecretValues: + type: object + properties: + value: + type: string + description: Value of secret in plain-text + example: changeme + rawValue: + type: string + format: byte + description: | + Value of secret in base64. + + This can be used to provide raw binary data when the `value` field is omitted. + example: Y2hhbmdlbWU= + + Secret: + type: object + allOf: + - $ref: "#/components/schemas/SecretDescription" + - $ref: "#/components/schemas/SecretValues" + + LogEntry: + type: object + required: + - name + - namespace + - instance + - timestamp + - text + properties: + name: + type: string + description: the function name + namespace: + type: string + description: the namespace of the function + instance: + type: string + description: the name/id of the specific function instance + timestamp: + type: string + description: the timestamp of when the log message was recorded + format: date-time + text: + type: string + description: raw log message content diff --git a/api-docs/swagger.yml b/api-docs/swagger.yml deleted file mode 100644 index 1e2710e3..00000000 --- a/api-docs/swagger.yml +++ /dev/null @@ -1,628 +0,0 @@ -swagger: '2.0' -info: - description: OpenFaaS API documentation - version: 0.8.12 - title: OpenFaaS API Gateway - license: - name: MIT -basePath: / -schemes: -- http -paths: - '/system/functions': - get: - summary: 'Get a list of deployed functions with: stats and image digest' - consumes: - - application/json - produces: - - application/json - responses: - '200': - description: List of deployed functions. - schema: - type: array - items: - $ref: '#/definitions/FunctionListEntry' - post: - summary: Deploy a new function. - description: '' - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - description: Function to deploy - required: true - schema: - $ref: '#/definitions/FunctionDefinition' - responses: - '202': - description: Accepted - '400': - description: Bad Request - '500': - description: Internal Server Error - put: - summary: Update a function. - description: '' - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - description: Function to update - required: true - schema: - $ref: '#/definitions/FunctionDefinition' - responses: - '200': - description: Accepted - '400': - description: Bad Request - '404': - description: Not Found - '500': - description: Internal Server Error - delete: - summary: Remove a deployed function. - description: '' - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - description: Function to delete - required: true - schema: - $ref: '#/definitions/DeleteFunctionRequest' - responses: - '200': - description: OK - '400': - description: Bad Request - '404': - description: Not Found - '500': - description: Internal Server Error - '/system/alert': - post: - summary: 'Event-sink for AlertManager, for auto-scaling' - description: 'Internal use for AlertManager, requires valid AlertManager alert JSON' - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - description: Incoming alert - schema: - type: object - example: |- - {"receiver": "scale-up", - "status": "firing", - "alerts": [{ - "status": "firing", - "labels": { - "alertname": "APIHighInvocationRate", - "code": "200", - "function_name": "func_nodeinfo", - "instance": "gateway:8080", - "job": "gateway", - "monitor": "faas-monitor", - "service": "gateway", - "severity": "major", - "value": "8.998200359928017" - }, - "annotations": { - "description": "High invocation total on gateway:8080", - "summary": "High invocation total on gateway:8080" - }, - "startsAt": "2017-03-15T15:52:57.805Z", - "endsAt": "0001-01-01T00:00:00Z", - "generatorURL": "http://4156cb797423:9090/graph?g0.expr=rate%28gateway_function_invocation_total%5B10s%5D%29+%3E+5\u0026g0.tab=0" - }], - "groupLabels": { - "alertname": "APIHighInvocationRate", - "service": "gateway" - }, - "commonLabels": { - "alertname": "APIHighInvocationRate", - "code": "200", - "function_name": "func_nodeinfo", - "instance": "gateway:8080", - "job": "gateway", - "monitor": "faas-monitor", - "service": "gateway", - "severity": "major", - "value": "8.998200359928017" - }, - "commonAnnotations": { - "description": "High invocation total on gateway:8080", - "summary": "High invocation total on gateway:8080" - }, - "externalURL": "http://f054879d97db:9093", - "version": "3", - "groupKey": 18195285354214864953 - } - responses: - '200': - description: Alert handled successfully - '500': - description: Internal error with swarm or request JSON invalid - '/async-function/{functionName}': - post: - summary: 'Invoke a function asynchronously in OpenFaaS' - description: >- - See https://docs.openfaas.com/reference/async/. - parameters: - - in: path - name: functionName - description: Function name - type: string - required: true - - in: body - name: input - description: (Optional) data to pass to function - schema: - type: string - format: binary - example: - '{"hello": "world"}' - required: false - responses: - '202': - description: Request accepted and queued - '404': - description: Not Found - '500': - description: Internal Server Error - '/function/{functionName}': - post: - summary: Invoke a function defined in OpenFaaS - parameters: - - in: path - name: functionName - description: Function name - type: string - required: true - - in: body - name: input - description: (Optional) data to pass to function - schema: - type: string - format: binary - example: - '{"hello": "world"}' - required: false - responses: - '200': - description: Value returned from function - '404': - description: Not Found - '500': - description: Internal server error - '/system/scale-function/{functionName}': - post: - summary: Scale a function - parameters: - - in: path - name: functionName - description: Function name - type: string - required: true - - in: body - name: input - description: Function to scale plus replica count - schema: - type: string - format: binary - example: - '{"service": "hello-world", "replicas": 10}' - required: false - responses: - '200': - description: Scaling OK - '202': - description: Scaling OK - '404': - description: Function not found - '500': - description: Error scaling function - '/system/function/{functionName}': - get: - summary: Get a summary of an OpenFaaS function - parameters: - - in: path - name: functionName - description: Function name - type: string - required: true - responses: - '200': - description: Function Summary - schema: - $ref: '#/definitions/FunctionListEntry' - '404': - description: Not Found - '500': - description: Internal Server Error - '/system/secrets': - get: - summary: 'Get a list of secret names and metadata from the provider' - consumes: - - application/json - produces: - - application/json - responses: - '200': - description: List of submitted secrets. - schema: - $ref: '#/definitions/SecretName' - post: - summary: Create a new secret. - description: '' - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - description: A new secret to create - required: true - schema: - $ref: '#/definitions/Secret' - responses: - '201': - description: Created - '400': - description: Bad Request - '500': - description: Internal Server Error - put: - summary: Update a secret. - description: '' - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - description: Secret to update - required: true - schema: - $ref: '#/definitions/Secret' - responses: - '200': - description: Ok - '400': - description: Bad Request - '404': - description: Not Found - '405': - description: Method Not Allowed. Secret update is not allowed in faas-swarm. - '500': - description: Internal Server Error - delete: - summary: Remove a secret. - description: '' - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - description: Secret to delete - required: true - schema: - $ref: '#/definitions/SecretName' - responses: - '204': - description: OK - '400': - description: Bad Request - '404': - description: Not Found - '500': - description: Internal Server Error - '/system/logs': - get: - summary: Get a stream of the logs for a specific function - produces: - - application/x-ndjson - parameters: - - in: query - name: name - description: Function name - type: string - required: true - - in: query - name: since - description: Only return logs after a specific date (RFC3339) - type: string - required: false - - in: query - name: tail - description: Sets the maximum number of log messages to return, <=0 means unlimited - type: integer - required: false - - in: query - name: follow - description: When true, the request will stream logs until the request timeout - type: boolean - required: false - responses: - '200': - description: Newline delimited stream of log messages - schema: - $ref: '#/definitions/LogEntry' - '404': - description: Not Found - '500': - description: Internal Server Error - '/system/info': - get: - summary: Get info such as provider version number and provider orchestrator - produces: - - application/json - responses: - '200': - description: Info result - schema: - $ref: '#/definitions/Info' - '404': - description: Provider does not support info endpoint - '500': - description: Internal Server Error - '/healthz': - get: - summary: Healthcheck - responses: - '200': - description: Healthy - '500': - description: Not healthy -securityDefinitions: - basicAuth: - type: basic -definitions: - Info: - type: object - properties: - provider: - type: object - description: The OpenFaaS Provider - properties: - provider: - type: string - example: faas-netes - orchestration: - type: string - example: kubernetes - version: - type: object - description: Version of the OpenFaaS Provider - properties: - commit_message: - type: string - example: Sample Message - sha: - type: string - example: 7108418d9dd6b329ddff40e7393b3166f8160a88 - release: - type: string - format: semver - example: 0.2.6 - version: - type: object - description: Version of the Gateway - properties: - commit_message: - type: string - example: Sample Message - sha: - type: string - example: 7108418d9dd6b329ddff40e7393b3166f8160a88 - release: - type: string - format: semver - example: 0.8.9 - arch: - type: string - description: "Platform architecture" - example: "x86_64" - required: - - provider - - version - DeleteFunctionRequest: - type: object - properties: - functionName: - type: string - description: Name of deployed function - example: nodeinfo - required: - - functionName - FunctionDefinition: - type: object - properties: - service: - type: string - description: Name of deployed function - example: nodeinfo - network: - type: string - description: Network, usually func_functions for Swarm (deprecated) - example: func_functions - image: - type: string - description: Docker image in accessible registry - example: functions/nodeinfo:latest - envProcess: - type: string - description: Process for watchdog to fork - example: node main.js - envVars: - type: object - additionalProperties: - type: string - description: Overrides to environmental variables - constraints: - type: array - items: - type: string - description: Constraints are specific to OpenFaaS Provider - example: "node.platform.os == linux" - labels: - description: A map of labels for making scheduling or routing decisions - type: object - additionalProperties: - type: string - example: - foo: bar - annotations: - description: A map of annotations for management, orchestration, events and build tasks - type: object - additionalProperties: - type: string - example: - topics: awesome-kafka-topic - foo: bar - secrets: - type: array - items: - type: string - description: An array of names of secrets that are required to be loaded from the Docker Swarm. - example: "secret-name-1" - registryAuth: - type: string - description: >- - Private registry base64-encoded basic auth (as present in - ~/.docker/config.json) - example: dXNlcjpwYXNzd29yZA== - limits: - type: object - properties: - memory: - type: string - example: "128M" - cpu: - type: string - example: "0.01" - requests: - type: object - properties: - memory: - type: string - example: "128M" - cpu: - type: string - example: "0.01" - readOnlyRootFilesystem: - type: boolean - description: Make the root filesystem of the function read-only - required: - - service - - image - - envProcess - FunctionListEntry: - type: object - properties: - name: - description: The name of the function - type: string - example: nodeinfo - image: - description: The fully qualified docker image name of the function - type: string - example: functions/nodeinfo:latest - invocationCount: - description: The amount of invocations for the specified function - type: number - format: integer - example: 1337 - replicas: - description: The current minimal ammount of replicas - type: number - format: integer - example: 2 - availableReplicas: - description: The current available amount of replicas - type: number - format: integer - example: 2 - envProcess: - description: Process for watchdog to fork - type: string - example: node main.js - labels: - description: A map of labels for making scheduling or routing decisions - type: object - additionalProperties: - type: string - example: - foo: bar - annotations: - description: A map of annotations for management, orchestration, events and build tasks - type: object - additionalProperties: - type: string - example: - topics: awesome-kafka-topic - foo: bar - required: - - name - - image - - invocationCount - - replicas - - availableReplicas - - envProcess - - labels - Secret: - type: object - properties: - name: - type: string - description: Name of secret - example: aws-key - value: - type: string - description: Value of secret in plain-text - example: changeme - required: - - name - LogEntry: - type: object - properties: - name: - type: string - description: the function name - instance: - type: string - description: the name/id of the specific function instance - timestamp: - type: string - format: date-time - description: the timestamp of when the log message was recorded - text: - type: string - description: raw log message content - SecretName: - type: object - properties: - name: - type: string - description: Name of secret - example: aws-key -externalDocs: - description: More documentation available on Github - url: 'https://github.com/openfaas/faas' diff --git a/gateway/go.mod b/gateway/go.mod index 740698c3..b2489c3c 100644 --- a/gateway/go.mod +++ b/gateway/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( github.com/docker/distribution v2.8.1+incompatible + github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/gorilla/mux v1.8.0 github.com/openfaas/faas-provider v0.19.1 github.com/openfaas/nats-queue-worker v0.0.0-20230117214128-3615ccb286cc diff --git a/gateway/go.sum b/gateway/go.sum index c07a2637..937d3103 100644 --- a/gateway/go.sum +++ b/gateway/go.sum @@ -41,6 +41,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -78,6 +80,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= +github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= diff --git a/gateway/handlers/alerthandler.go b/gateway/handlers/alerthandler.go index 442e878d..55f95744 100644 --- a/gateway/handlers/alerthandler.go +++ b/gateway/handlers/alerthandler.go @@ -44,7 +44,7 @@ func MakeAlertHandler(service scaling.ServiceQuery, defaultNamespace string) htt return } - errors := handleAlerts(&req, service, defaultNamespace) + errors := handleAlerts(req, service, defaultNamespace) if len(errors) > 0 { log.Println(errors) var errorOutput string @@ -60,7 +60,7 @@ func MakeAlertHandler(service scaling.ServiceQuery, defaultNamespace string) htt } } -func handleAlerts(req *requests.PrometheusAlert, service scaling.ServiceQuery, defaultNamespace string) []error { +func handleAlerts(req requests.PrometheusAlert, service scaling.ServiceQuery, defaultNamespace string) []error { var errors []error for _, alert := range req.Alerts { if err := scaleService(alert, service, defaultNamespace); err != nil { diff --git a/gateway/models/model_delete_function_request.go b/gateway/models/model_delete_function_request.go new file mode 100644 index 00000000..08aa44e6 --- /dev/null +++ b/gateway/models/model_delete_function_request.go @@ -0,0 +1,32 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// DeleteFunctionRequest is an object. +type DeleteFunctionRequest struct { + // FunctionName: Name of deployed function + FunctionName string `json:"functionName" mapstructure:"functionName"` +} + +// Validate implements basic validation for this model +func (m DeleteFunctionRequest) Validate() error { + return validation.Errors{}.Filter() +} + +// GetFunctionName returns the FunctionName property +func (m DeleteFunctionRequest) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *DeleteFunctionRequest) SetFunctionName(val string) { + m.FunctionName = val +} diff --git a/gateway/models/model_function_deployment.go b/gateway/models/model_function_deployment.go new file mode 100644 index 00000000..63eba38d --- /dev/null +++ b/gateway/models/model_function_deployment.go @@ -0,0 +1,218 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// FunctionDeployment is an object. +type FunctionDeployment struct { + // Annotations: A map of annotations for management, orchestration, events and build tasks + Annotations map[string]string `json:"annotations,omitempty" mapstructure:"annotations,omitempty"` + // Constraints: + Constraints []string `json:"constraints,omitempty" mapstructure:"constraints,omitempty"` + // EnvProcess: Process for watchdog to fork, i.e. the command to start the function process. + // + // This value configures the `fprocess` env variable. + EnvProcess string `json:"envProcess,omitempty" mapstructure:"envProcess,omitempty"` + // EnvVars: Overrides to environmental variables + EnvVars map[string]string `json:"envVars,omitempty" mapstructure:"envVars,omitempty"` + // Image: Docker image in accessible registry + Image string `json:"image" mapstructure:"image"` + // Labels: A map of labels for making scheduling or routing decisions + Labels map[string]string `json:"labels,omitempty" mapstructure:"labels,omitempty"` + // Limits: + Limits *FunctionResources `json:"limits,omitempty" mapstructure:"limits,omitempty"` + // Namespace: Namespace to deploy function to. When omitted, the default namespace is used, typically this is `openfaas-fn` but is configured by the provider. + Namespace string `json:"namespace,omitempty" mapstructure:"namespace,omitempty"` + // Network: Deprecated: Network, usually func_functions for Swarm. + // + // This value is completely ignored. + Network string `json:"network,omitempty" mapstructure:"network,omitempty"` + // ReadOnlyRootFilesystem: Make the root filesystem of the function read-only + ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty" mapstructure:"readOnlyRootFilesystem,omitempty"` + // RegistryAuth: Deprecated: Private registry base64-encoded basic auth (as present in ~/.docker/config.json) + // + // Use a Kubernetes Secret with registry-auth secret type to provide this value instead. + // + // This value is completely ignored. + RegistryAuth string `json:"registryAuth,omitempty" mapstructure:"registryAuth,omitempty"` + // Requests: + Requests *FunctionResources `json:"requests,omitempty" mapstructure:"requests,omitempty"` + // Secrets: + Secrets []string `json:"secrets,omitempty" mapstructure:"secrets,omitempty"` + // Service: Name of deployed function + Service string `json:"service" mapstructure:"service"` +} + +// Validate implements basic validation for this model +func (m FunctionDeployment) Validate() error { + return validation.Errors{ + "annotations": validation.Validate( + m.Annotations, + ), + "constraints": validation.Validate( + m.Constraints, + ), + "envVars": validation.Validate( + m.EnvVars, + ), + "labels": validation.Validate( + m.Labels, + ), + "limits": validation.Validate( + m.Limits, + ), + "requests": validation.Validate( + m.Requests, + ), + "secrets": validation.Validate( + m.Secrets, + ), + }.Filter() +} + +// GetAnnotations returns the Annotations property +func (m FunctionDeployment) GetAnnotations() map[string]string { + return m.Annotations +} + +// SetAnnotations sets the Annotations property +func (m *FunctionDeployment) SetAnnotations(val map[string]string) { + m.Annotations = val +} + +// GetConstraints returns the Constraints property +func (m FunctionDeployment) GetConstraints() []string { + return m.Constraints +} + +// SetConstraints sets the Constraints property +func (m *FunctionDeployment) SetConstraints(val []string) { + m.Constraints = val +} + +// GetEnvProcess returns the EnvProcess property +func (m FunctionDeployment) GetEnvProcess() string { + return m.EnvProcess +} + +// SetEnvProcess sets the EnvProcess property +func (m *FunctionDeployment) SetEnvProcess(val string) { + m.EnvProcess = val +} + +// GetEnvVars returns the EnvVars property +func (m FunctionDeployment) GetEnvVars() map[string]string { + return m.EnvVars +} + +// SetEnvVars sets the EnvVars property +func (m *FunctionDeployment) SetEnvVars(val map[string]string) { + m.EnvVars = val +} + +// GetImage returns the Image property +func (m FunctionDeployment) GetImage() string { + return m.Image +} + +// SetImage sets the Image property +func (m *FunctionDeployment) SetImage(val string) { + m.Image = val +} + +// GetLabels returns the Labels property +func (m FunctionDeployment) GetLabels() map[string]string { + return m.Labels +} + +// SetLabels sets the Labels property +func (m *FunctionDeployment) SetLabels(val map[string]string) { + m.Labels = val +} + +// GetLimits returns the Limits property +func (m FunctionDeployment) GetLimits() *FunctionResources { + return m.Limits +} + +// SetLimits sets the Limits property +func (m *FunctionDeployment) SetLimits(val *FunctionResources) { + m.Limits = val +} + +// GetNamespace returns the Namespace property +func (m FunctionDeployment) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *FunctionDeployment) SetNamespace(val string) { + m.Namespace = val +} + +// GetNetwork returns the Network property +func (m FunctionDeployment) GetNetwork() string { + return m.Network +} + +// SetNetwork sets the Network property +func (m *FunctionDeployment) SetNetwork(val string) { + m.Network = val +} + +// GetReadOnlyRootFilesystem returns the ReadOnlyRootFilesystem property +func (m FunctionDeployment) GetReadOnlyRootFilesystem() bool { + return m.ReadOnlyRootFilesystem +} + +// SetReadOnlyRootFilesystem sets the ReadOnlyRootFilesystem property +func (m *FunctionDeployment) SetReadOnlyRootFilesystem(val bool) { + m.ReadOnlyRootFilesystem = val +} + +// GetRegistryAuth returns the RegistryAuth property +func (m FunctionDeployment) GetRegistryAuth() string { + return m.RegistryAuth +} + +// SetRegistryAuth sets the RegistryAuth property +func (m *FunctionDeployment) SetRegistryAuth(val string) { + m.RegistryAuth = val +} + +// GetRequests returns the Requests property +func (m FunctionDeployment) GetRequests() *FunctionResources { + return m.Requests +} + +// SetRequests sets the Requests property +func (m *FunctionDeployment) SetRequests(val *FunctionResources) { + m.Requests = val +} + +// GetSecrets returns the Secrets property +func (m FunctionDeployment) GetSecrets() []string { + return m.Secrets +} + +// SetSecrets sets the Secrets property +func (m *FunctionDeployment) SetSecrets(val []string) { + m.Secrets = val +} + +// GetService returns the Service property +func (m FunctionDeployment) GetService() string { + return m.Service +} + +// SetService sets the Service property +func (m *FunctionDeployment) SetService(val string) { + m.Service = val +} diff --git a/gateway/models/model_function_resources.go b/gateway/models/model_function_resources.go new file mode 100644 index 00000000..6674f81c --- /dev/null +++ b/gateway/models/model_function_resources.go @@ -0,0 +1,44 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// FunctionResources is an object. +type FunctionResources struct { + // Cpu: The amount of cpu that is allocated for the function + Cpu string `json:"cpu,omitempty" mapstructure:"cpu,omitempty"` + // Memory: The amount of memory that is allocated for the function + Memory string `json:"memory,omitempty" mapstructure:"memory,omitempty"` +} + +// Validate implements basic validation for this model +func (m FunctionResources) Validate() error { + return validation.Errors{}.Filter() +} + +// GetCpu returns the Cpu property +func (m FunctionResources) GetCpu() string { + return m.Cpu +} + +// SetCpu sets the Cpu property +func (m *FunctionResources) SetCpu(val string) { + m.Cpu = val +} + +// GetMemory returns the Memory property +func (m FunctionResources) GetMemory() string { + return m.Memory +} + +// SetMemory sets the Memory property +func (m *FunctionResources) SetMemory(val string) { + m.Memory = val +} diff --git a/gateway/models/model_function_status.go b/gateway/models/model_function_status.go new file mode 100644 index 00000000..ad8b524a --- /dev/null +++ b/gateway/models/model_function_status.go @@ -0,0 +1,251 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" + "time" +) + +// FunctionStatus is an object. +type FunctionStatus struct { + // Annotations: A map of annotations for management, orchestration, events and build tasks + Annotations map[string]string `json:"annotations,omitempty" mapstructure:"annotations,omitempty"` + // AvailableReplicas: The current available amount of replicas + AvailableReplicas float32 `json:"availableReplicas,omitempty" mapstructure:"availableReplicas,omitempty"` + // Constraints: + Constraints []string `json:"constraints,omitempty" mapstructure:"constraints,omitempty"` + // CreatedAt: is the time read back from the faas backend's + // data store for when the function or its container was created. + CreatedAt time.Time `json:"createdAt,omitempty" mapstructure:"createdAt,omitempty"` + // EnvProcess: Process for watchdog to fork + EnvProcess string `json:"envProcess,omitempty" mapstructure:"envProcess,omitempty"` + // EnvVars: environment variables for the function runtime + EnvVars map[string]string `json:"envVars,omitempty" mapstructure:"envVars,omitempty"` + // Image: The fully qualified docker image name of the function + Image string `json:"image" mapstructure:"image"` + // InvocationCount: The amount of invocations for the specified function + InvocationCount float32 `json:"invocationCount,omitempty" mapstructure:"invocationCount,omitempty"` + // Labels: A map of labels for making scheduling or routing decisions + Labels map[string]string `json:"labels,omitempty" mapstructure:"labels,omitempty"` + // Limits: + Limits *FunctionResources `json:"limits,omitempty" mapstructure:"limits,omitempty"` + // Name: The name of the function + Name string `json:"name" mapstructure:"name"` + // Namespace: The namespace of the function + Namespace string `json:"namespace,omitempty" mapstructure:"namespace,omitempty"` + // ReadOnlyRootFilesystem: removes write-access from the root filesystem mount-point. + ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty" mapstructure:"readOnlyRootFilesystem,omitempty"` + // Replicas: The current minimal ammount of replicas + Replicas float32 `json:"replicas,omitempty" mapstructure:"replicas,omitempty"` + // Requests: + Requests *FunctionResources `json:"requests,omitempty" mapstructure:"requests,omitempty"` + // Secrets: + Secrets []string `json:"secrets,omitempty" mapstructure:"secrets,omitempty"` + // Usage: + Usage *FunctionUsage `json:"usage,omitempty" mapstructure:"usage,omitempty"` +} + +// Validate implements basic validation for this model +func (m FunctionStatus) Validate() error { + return validation.Errors{ + "annotations": validation.Validate( + m.Annotations, + ), + "constraints": validation.Validate( + m.Constraints, + ), + "envVars": validation.Validate( + m.EnvVars, + ), + "labels": validation.Validate( + m.Labels, + ), + "limits": validation.Validate( + m.Limits, + ), + "requests": validation.Validate( + m.Requests, + ), + "secrets": validation.Validate( + m.Secrets, + ), + "usage": validation.Validate( + m.Usage, + ), + }.Filter() +} + +// GetAnnotations returns the Annotations property +func (m FunctionStatus) GetAnnotations() map[string]string { + return m.Annotations +} + +// SetAnnotations sets the Annotations property +func (m *FunctionStatus) SetAnnotations(val map[string]string) { + m.Annotations = val +} + +// GetAvailableReplicas returns the AvailableReplicas property +func (m FunctionStatus) GetAvailableReplicas() float32 { + return m.AvailableReplicas +} + +// SetAvailableReplicas sets the AvailableReplicas property +func (m *FunctionStatus) SetAvailableReplicas(val float32) { + m.AvailableReplicas = val +} + +// GetConstraints returns the Constraints property +func (m FunctionStatus) GetConstraints() []string { + return m.Constraints +} + +// SetConstraints sets the Constraints property +func (m *FunctionStatus) SetConstraints(val []string) { + m.Constraints = val +} + +// GetCreatedAt returns the CreatedAt property +func (m FunctionStatus) GetCreatedAt() time.Time { + return m.CreatedAt +} + +// SetCreatedAt sets the CreatedAt property +func (m *FunctionStatus) SetCreatedAt(val time.Time) { + m.CreatedAt = val +} + +// GetEnvProcess returns the EnvProcess property +func (m FunctionStatus) GetEnvProcess() string { + return m.EnvProcess +} + +// SetEnvProcess sets the EnvProcess property +func (m *FunctionStatus) SetEnvProcess(val string) { + m.EnvProcess = val +} + +// GetEnvVars returns the EnvVars property +func (m FunctionStatus) GetEnvVars() map[string]string { + return m.EnvVars +} + +// SetEnvVars sets the EnvVars property +func (m *FunctionStatus) SetEnvVars(val map[string]string) { + m.EnvVars = val +} + +// GetImage returns the Image property +func (m FunctionStatus) GetImage() string { + return m.Image +} + +// SetImage sets the Image property +func (m *FunctionStatus) SetImage(val string) { + m.Image = val +} + +// GetInvocationCount returns the InvocationCount property +func (m FunctionStatus) GetInvocationCount() float32 { + return m.InvocationCount +} + +// SetInvocationCount sets the InvocationCount property +func (m *FunctionStatus) SetInvocationCount(val float32) { + m.InvocationCount = val +} + +// GetLabels returns the Labels property +func (m FunctionStatus) GetLabels() map[string]string { + return m.Labels +} + +// SetLabels sets the Labels property +func (m *FunctionStatus) SetLabels(val map[string]string) { + m.Labels = val +} + +// GetLimits returns the Limits property +func (m FunctionStatus) GetLimits() *FunctionResources { + return m.Limits +} + +// SetLimits sets the Limits property +func (m *FunctionStatus) SetLimits(val *FunctionResources) { + m.Limits = val +} + +// GetName returns the Name property +func (m FunctionStatus) GetName() string { + return m.Name +} + +// SetName sets the Name property +func (m *FunctionStatus) SetName(val string) { + m.Name = val +} + +// GetNamespace returns the Namespace property +func (m FunctionStatus) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *FunctionStatus) SetNamespace(val string) { + m.Namespace = val +} + +// GetReadOnlyRootFilesystem returns the ReadOnlyRootFilesystem property +func (m FunctionStatus) GetReadOnlyRootFilesystem() bool { + return m.ReadOnlyRootFilesystem +} + +// SetReadOnlyRootFilesystem sets the ReadOnlyRootFilesystem property +func (m *FunctionStatus) SetReadOnlyRootFilesystem(val bool) { + m.ReadOnlyRootFilesystem = val +} + +// GetReplicas returns the Replicas property +func (m FunctionStatus) GetReplicas() float32 { + return m.Replicas +} + +// SetReplicas sets the Replicas property +func (m *FunctionStatus) SetReplicas(val float32) { + m.Replicas = val +} + +// GetRequests returns the Requests property +func (m FunctionStatus) GetRequests() *FunctionResources { + return m.Requests +} + +// SetRequests sets the Requests property +func (m *FunctionStatus) SetRequests(val *FunctionResources) { + m.Requests = val +} + +// GetSecrets returns the Secrets property +func (m FunctionStatus) GetSecrets() []string { + return m.Secrets +} + +// SetSecrets sets the Secrets property +func (m *FunctionStatus) SetSecrets(val []string) { + m.Secrets = val +} + +// GetUsage returns the Usage property +func (m FunctionStatus) GetUsage() *FunctionUsage { + return m.Usage +} + +// SetUsage sets the Usage property +func (m *FunctionStatus) SetUsage(val *FunctionUsage) { + m.Usage = val +} diff --git a/gateway/models/model_function_usage.go b/gateway/models/model_function_usage.go new file mode 100644 index 00000000..a5bd4431 --- /dev/null +++ b/gateway/models/model_function_usage.go @@ -0,0 +1,45 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// FunctionUsage is an object. +type FunctionUsage struct { + // Cpu: is the increase in CPU usage since the last measurement + // equivalent to Kubernetes' concept of millicores. + Cpu float64 `json:"cpu,omitempty" mapstructure:"cpu,omitempty"` + // TotalMemoryBytes: is the total memory usage in bytes. + TotalMemoryBytes float64 `json:"totalMemoryBytes,omitempty" mapstructure:"totalMemoryBytes,omitempty"` +} + +// Validate implements basic validation for this model +func (m FunctionUsage) Validate() error { + return validation.Errors{}.Filter() +} + +// GetCpu returns the Cpu property +func (m FunctionUsage) GetCpu() float64 { + return m.Cpu +} + +// SetCpu sets the Cpu property +func (m *FunctionUsage) SetCpu(val float64) { + m.Cpu = val +} + +// GetTotalMemoryBytes returns the TotalMemoryBytes property +func (m FunctionUsage) GetTotalMemoryBytes() float64 { + return m.TotalMemoryBytes +} + +// SetTotalMemoryBytes sets the TotalMemoryBytes property +func (m *FunctionUsage) SetTotalMemoryBytes(val float64) { + m.TotalMemoryBytes = val +} diff --git a/gateway/models/model_gateway_info.go b/gateway/models/model_gateway_info.go new file mode 100644 index 00000000..c6243c44 --- /dev/null +++ b/gateway/models/model_gateway_info.go @@ -0,0 +1,63 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// GatewayInfo is an object. +type GatewayInfo struct { + // Arch: Platform architecture + Arch string `json:"arch" mapstructure:"arch"` + // Provider: + Provider *ProviderInfo `json:"provider" mapstructure:"provider"` + // Version: version of the gateway + Version *VersionInfo `json:"version" mapstructure:"version"` +} + +// Validate implements basic validation for this model +func (m GatewayInfo) Validate() error { + return validation.Errors{ + "provider": validation.Validate( + m.Provider, + ), + "version": validation.Validate( + m.Version, + ), + }.Filter() +} + +// GetArch returns the Arch property +func (m GatewayInfo) GetArch() string { + return m.Arch +} + +// SetArch sets the Arch property +func (m *GatewayInfo) SetArch(val string) { + m.Arch = val +} + +// GetProvider returns the Provider property +func (m GatewayInfo) GetProvider() *ProviderInfo { + return m.Provider +} + +// SetProvider sets the Provider property +func (m *GatewayInfo) SetProvider(val *ProviderInfo) { + m.Provider = val +} + +// GetVersion returns the Version property +func (m GatewayInfo) GetVersion() *VersionInfo { + return m.Version +} + +// SetVersion sets the Version property +func (m *GatewayInfo) SetVersion(val *VersionInfo) { + m.Version = val +} diff --git a/gateway/models/model_get_function_logs_query_parameters.go b/gateway/models/model_get_function_logs_query_parameters.go new file mode 100644 index 00000000..059cbea0 --- /dev/null +++ b/gateway/models/model_get_function_logs_query_parameters.go @@ -0,0 +1,93 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" + "time" +) + +// GetFunctionLogsQueryParameters is an object. +type GetFunctionLogsQueryParameters struct { + // Name: Function name + Name string `json:"name" mapstructure:"name"` + // Namespace: Namespace of the function + Namespace string `json:"namespace,omitempty" mapstructure:"namespace,omitempty"` + // Instance: Instance of the function + Instance string `json:"instance,omitempty" mapstructure:"instance,omitempty"` + // Tail: Sets the maximum number of log messages to return, <=0 means unlimited + Tail int32 `json:"tail,omitempty" mapstructure:"tail,omitempty"` + // Follow: When true, the request will stream logs until the request timeout + Follow bool `json:"follow,omitempty" mapstructure:"follow,omitempty"` + // Since: Only return logs after a specific date (RFC3339) + Since time.Time `json:"since" mapstructure:"since"` +} + +// Validate implements basic validation for this model +func (m GetFunctionLogsQueryParameters) Validate() error { + return validation.Errors{}.Filter() +} + +// GetName returns the Name property +func (m GetFunctionLogsQueryParameters) GetName() string { + return m.Name +} + +// SetName sets the Name property +func (m *GetFunctionLogsQueryParameters) SetName(val string) { + m.Name = val +} + +// GetNamespace returns the Namespace property +func (m GetFunctionLogsQueryParameters) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *GetFunctionLogsQueryParameters) SetNamespace(val string) { + m.Namespace = val +} + +// GetInstance returns the Instance property +func (m GetFunctionLogsQueryParameters) GetInstance() string { + return m.Instance +} + +// SetInstance sets the Instance property +func (m *GetFunctionLogsQueryParameters) SetInstance(val string) { + m.Instance = val +} + +// GetTail returns the Tail property +func (m GetFunctionLogsQueryParameters) GetTail() int32 { + return m.Tail +} + +// SetTail sets the Tail property +func (m *GetFunctionLogsQueryParameters) SetTail(val int32) { + m.Tail = val +} + +// GetFollow returns the Follow property +func (m GetFunctionLogsQueryParameters) GetFollow() bool { + return m.Follow +} + +// SetFollow sets the Follow property +func (m *GetFunctionLogsQueryParameters) SetFollow(val bool) { + m.Follow = val +} + +// GetSince returns the Since property +func (m GetFunctionLogsQueryParameters) GetSince() time.Time { + return m.Since +} + +// SetSince sets the Since property +func (m *GetFunctionLogsQueryParameters) SetSince(val time.Time) { + m.Since = val +} diff --git a/gateway/models/model_get_function_status_query_parameters.go b/gateway/models/model_get_function_status_query_parameters.go new file mode 100644 index 00000000..ec7b3ba9 --- /dev/null +++ b/gateway/models/model_get_function_status_query_parameters.go @@ -0,0 +1,44 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// GetFunctionStatusQueryParameters is an object. +type GetFunctionStatusQueryParameters struct { + // FunctionName: Function name + FunctionName string `json:"functionName" mapstructure:"functionName"` + // Namespace: Namespace of the function + Namespace string `json:"namespace,omitempty" mapstructure:"namespace,omitempty"` +} + +// Validate implements basic validation for this model +func (m GetFunctionStatusQueryParameters) Validate() error { + return validation.Errors{}.Filter() +} + +// GetFunctionName returns the FunctionName property +func (m GetFunctionStatusQueryParameters) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *GetFunctionStatusQueryParameters) SetFunctionName(val string) { + m.FunctionName = val +} + +// GetNamespace returns the Namespace property +func (m GetFunctionStatusQueryParameters) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *GetFunctionStatusQueryParameters) SetNamespace(val string) { + m.Namespace = val +} diff --git a/gateway/models/model_invoke_async_namespaced_query_parameters.go b/gateway/models/model_invoke_async_namespaced_query_parameters.go new file mode 100644 index 00000000..5178f381 --- /dev/null +++ b/gateway/models/model_invoke_async_namespaced_query_parameters.go @@ -0,0 +1,44 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// InvokeAsyncNamespacedQueryParameters is an object. +type InvokeAsyncNamespacedQueryParameters struct { + // FunctionName: Function name + FunctionName string `json:"functionName" mapstructure:"functionName"` + // Namespace: Namespace of the function + Namespace string `json:"namespace" mapstructure:"namespace"` +} + +// Validate implements basic validation for this model +func (m InvokeAsyncNamespacedQueryParameters) Validate() error { + return validation.Errors{}.Filter() +} + +// GetFunctionName returns the FunctionName property +func (m InvokeAsyncNamespacedQueryParameters) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *InvokeAsyncNamespacedQueryParameters) SetFunctionName(val string) { + m.FunctionName = val +} + +// GetNamespace returns the Namespace property +func (m InvokeAsyncNamespacedQueryParameters) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *InvokeAsyncNamespacedQueryParameters) SetNamespace(val string) { + m.Namespace = val +} diff --git a/gateway/models/model_invoke_async_query_parameters.go b/gateway/models/model_invoke_async_query_parameters.go new file mode 100644 index 00000000..5efc3ad5 --- /dev/null +++ b/gateway/models/model_invoke_async_query_parameters.go @@ -0,0 +1,32 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// InvokeAsyncQueryParameters is an object. +type InvokeAsyncQueryParameters struct { + // FunctionName: Function name + FunctionName string `json:"functionName" mapstructure:"functionName"` +} + +// Validate implements basic validation for this model +func (m InvokeAsyncQueryParameters) Validate() error { + return validation.Errors{}.Filter() +} + +// GetFunctionName returns the FunctionName property +func (m InvokeAsyncQueryParameters) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *InvokeAsyncQueryParameters) SetFunctionName(val string) { + m.FunctionName = val +} diff --git a/gateway/models/model_invoke_function_namespaced_query_parameters.go b/gateway/models/model_invoke_function_namespaced_query_parameters.go new file mode 100644 index 00000000..502ac1be --- /dev/null +++ b/gateway/models/model_invoke_function_namespaced_query_parameters.go @@ -0,0 +1,44 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// InvokeFunctionNamespacedQueryParameters is an object. +type InvokeFunctionNamespacedQueryParameters struct { + // FunctionName: Function name + FunctionName string `json:"functionName" mapstructure:"functionName"` + // Namespace: Namespace of the function + Namespace string `json:"namespace" mapstructure:"namespace"` +} + +// Validate implements basic validation for this model +func (m InvokeFunctionNamespacedQueryParameters) Validate() error { + return validation.Errors{}.Filter() +} + +// GetFunctionName returns the FunctionName property +func (m InvokeFunctionNamespacedQueryParameters) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *InvokeFunctionNamespacedQueryParameters) SetFunctionName(val string) { + m.FunctionName = val +} + +// GetNamespace returns the Namespace property +func (m InvokeFunctionNamespacedQueryParameters) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *InvokeFunctionNamespacedQueryParameters) SetNamespace(val string) { + m.Namespace = val +} diff --git a/gateway/models/model_invoke_function_query_parameters.go b/gateway/models/model_invoke_function_query_parameters.go new file mode 100644 index 00000000..c98254ab --- /dev/null +++ b/gateway/models/model_invoke_function_query_parameters.go @@ -0,0 +1,32 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// InvokeFunctionQueryParameters is an object. +type InvokeFunctionQueryParameters struct { + // FunctionName: Function name + FunctionName string `json:"functionName" mapstructure:"functionName"` +} + +// Validate implements basic validation for this model +func (m InvokeFunctionQueryParameters) Validate() error { + return validation.Errors{}.Filter() +} + +// GetFunctionName returns the FunctionName property +func (m InvokeFunctionQueryParameters) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *InvokeFunctionQueryParameters) SetFunctionName(val string) { + m.FunctionName = val +} diff --git a/gateway/models/model_log_entry.go b/gateway/models/model_log_entry.go new file mode 100644 index 00000000..620d9861 --- /dev/null +++ b/gateway/models/model_log_entry.go @@ -0,0 +1,81 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" + "time" +) + +// LogEntry is an object. +type LogEntry struct { + // Instance: the name/id of the specific function instance + Instance string `json:"instance" mapstructure:"instance"` + // Name: the function name + Name string `json:"name" mapstructure:"name"` + // Namespace: the namespace of the function + Namespace string `json:"namespace" mapstructure:"namespace"` + // Text: raw log message content + Text string `json:"text" mapstructure:"text"` + // Timestamp: the timestamp of when the log message was recorded + Timestamp time.Time `json:"timestamp" mapstructure:"timestamp"` +} + +// Validate implements basic validation for this model +func (m LogEntry) Validate() error { + return validation.Errors{}.Filter() +} + +// GetInstance returns the Instance property +func (m LogEntry) GetInstance() string { + return m.Instance +} + +// SetInstance sets the Instance property +func (m *LogEntry) SetInstance(val string) { + m.Instance = val +} + +// GetName returns the Name property +func (m LogEntry) GetName() string { + return m.Name +} + +// SetName sets the Name property +func (m *LogEntry) SetName(val string) { + m.Name = val +} + +// GetNamespace returns the Namespace property +func (m LogEntry) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *LogEntry) SetNamespace(val string) { + m.Namespace = val +} + +// GetText returns the Text property +func (m LogEntry) GetText() string { + return m.Text +} + +// SetText sets the Text property +func (m *LogEntry) SetText(val string) { + m.Text = val +} + +// GetTimestamp returns the Timestamp property +func (m LogEntry) GetTimestamp() time.Time { + return m.Timestamp +} + +// SetTimestamp sets the Timestamp property +func (m *LogEntry) SetTimestamp(val time.Time) { + m.Timestamp = val +} diff --git a/gateway/models/model_prometheus_alert.go b/gateway/models/model_prometheus_alert.go new file mode 100644 index 00000000..625ecaf3 --- /dev/null +++ b/gateway/models/model_prometheus_alert.go @@ -0,0 +1,60 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// PrometheusAlert is an object. Prometheus alert produced by AlertManager. This is only a subset of the full alert payload. +type PrometheusAlert struct { + // Alerts: The list of alerts + Alerts []PrometheusInnerAlert `json:"alerts" mapstructure:"alerts"` + // Receiver: The name of the receiver + Receiver string `json:"receiver" mapstructure:"receiver"` + // Status: The status of the alert + Status string `json:"status" mapstructure:"status"` +} + +// Validate implements basic validation for this model +func (m PrometheusAlert) Validate() error { + return validation.Errors{ + "alerts": validation.Validate( + m.Alerts, validation.NotNil, + ), + }.Filter() +} + +// GetAlerts returns the Alerts property +func (m PrometheusAlert) GetAlerts() []PrometheusInnerAlert { + return m.Alerts +} + +// SetAlerts sets the Alerts property +func (m *PrometheusAlert) SetAlerts(val []PrometheusInnerAlert) { + m.Alerts = val +} + +// GetReceiver returns the Receiver property +func (m PrometheusAlert) GetReceiver() string { + return m.Receiver +} + +// SetReceiver sets the Receiver property +func (m *PrometheusAlert) SetReceiver(val string) { + m.Receiver = val +} + +// GetStatus returns the Status property +func (m PrometheusAlert) GetStatus() string { + return m.Status +} + +// SetStatus sets the Status property +func (m *PrometheusAlert) SetStatus(val string) { + m.Status = val +} diff --git a/gateway/models/model_prometheus_inner_alert.go b/gateway/models/model_prometheus_inner_alert.go new file mode 100644 index 00000000..f5794de0 --- /dev/null +++ b/gateway/models/model_prometheus_inner_alert.go @@ -0,0 +1,48 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// PrometheusInnerAlert is an object. A single alert produced by Prometheus +type PrometheusInnerAlert struct { + // Labels: A single label of a Prometheus alert + Labels PrometheusInnerAlertLabel `json:"labels" mapstructure:"labels"` + // Status: The status of the alert + Status string `json:"status" mapstructure:"status"` +} + +// Validate implements basic validation for this model +func (m PrometheusInnerAlert) Validate() error { + return validation.Errors{ + "labels": validation.Validate( + m.Labels, validation.NotNil, + ), + }.Filter() +} + +// GetLabels returns the Labels property +func (m PrometheusInnerAlert) GetLabels() PrometheusInnerAlertLabel { + return m.Labels +} + +// SetLabels sets the Labels property +func (m *PrometheusInnerAlert) SetLabels(val PrometheusInnerAlertLabel) { + m.Labels = val +} + +// GetStatus returns the Status property +func (m PrometheusInnerAlert) GetStatus() string { + return m.Status +} + +// SetStatus sets the Status property +func (m *PrometheusInnerAlert) SetStatus(val string) { + m.Status = val +} diff --git a/gateway/models/model_prometheus_inner_alert_label.go b/gateway/models/model_prometheus_inner_alert_label.go new file mode 100644 index 00000000..e2792c81 --- /dev/null +++ b/gateway/models/model_prometheus_inner_alert_label.go @@ -0,0 +1,44 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// PrometheusInnerAlertLabel is an object. A single label of a Prometheus alert +type PrometheusInnerAlertLabel struct { + // Alertname: The name of the alert + Alertname string `json:"alertname" mapstructure:"alertname"` + // FunctionName: The name of the function + FunctionName string `json:"function_name" mapstructure:"function_name"` +} + +// Validate implements basic validation for this model +func (m PrometheusInnerAlertLabel) Validate() error { + return validation.Errors{}.Filter() +} + +// GetAlertname returns the Alertname property +func (m PrometheusInnerAlertLabel) GetAlertname() string { + return m.Alertname +} + +// SetAlertname sets the Alertname property +func (m *PrometheusInnerAlertLabel) SetAlertname(val string) { + m.Alertname = val +} + +// GetFunctionName returns the FunctionName property +func (m PrometheusInnerAlertLabel) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *PrometheusInnerAlertLabel) SetFunctionName(val string) { + m.FunctionName = val +} diff --git a/gateway/models/model_provider_info.go b/gateway/models/model_provider_info.go new file mode 100644 index 00000000..6784803c --- /dev/null +++ b/gateway/models/model_provider_info.go @@ -0,0 +1,60 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// ProviderInfo is an object. +type ProviderInfo struct { + // Orchestration: + Orchestration string `json:"orchestration" mapstructure:"orchestration"` + // Provider: The orchestration provider / implementation + Provider string `json:"provider" mapstructure:"provider"` + // Version: The version of the provider + Version *VersionInfo `json:"version" mapstructure:"version"` +} + +// Validate implements basic validation for this model +func (m ProviderInfo) Validate() error { + return validation.Errors{ + "version": validation.Validate( + m.Version, + ), + }.Filter() +} + +// GetOrchestration returns the Orchestration property +func (m ProviderInfo) GetOrchestration() string { + return m.Orchestration +} + +// SetOrchestration sets the Orchestration property +func (m *ProviderInfo) SetOrchestration(val string) { + m.Orchestration = val +} + +// GetProvider returns the Provider property +func (m ProviderInfo) GetProvider() string { + return m.Provider +} + +// SetProvider sets the Provider property +func (m *ProviderInfo) SetProvider(val string) { + m.Provider = val +} + +// GetVersion returns the Version property +func (m ProviderInfo) GetVersion() *VersionInfo { + return m.Version +} + +// SetVersion sets the Version property +func (m *ProviderInfo) SetVersion(val *VersionInfo) { + m.Version = val +} diff --git a/gateway/models/model_scale_function_query_parameters.go b/gateway/models/model_scale_function_query_parameters.go new file mode 100644 index 00000000..e68e6f1c --- /dev/null +++ b/gateway/models/model_scale_function_query_parameters.go @@ -0,0 +1,32 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// ScaleFunctionQueryParameters is an object. +type ScaleFunctionQueryParameters struct { + // FunctionName: Function name + FunctionName string `json:"functionName" mapstructure:"functionName"` +} + +// Validate implements basic validation for this model +func (m ScaleFunctionQueryParameters) Validate() error { + return validation.Errors{}.Filter() +} + +// GetFunctionName returns the FunctionName property +func (m ScaleFunctionQueryParameters) GetFunctionName() string { + return m.FunctionName +} + +// SetFunctionName sets the FunctionName property +func (m *ScaleFunctionQueryParameters) SetFunctionName(val string) { + m.FunctionName = val +} diff --git a/gateway/models/model_scale_service_request.go b/gateway/models/model_scale_service_request.go new file mode 100644 index 00000000..c6f18929 --- /dev/null +++ b/gateway/models/model_scale_service_request.go @@ -0,0 +1,48 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// ScaleServiceRequest is an object. +type ScaleServiceRequest struct { + // Replicas: Number of replicas to scale to + Replicas int64 `json:"replicas" mapstructure:"replicas"` + // ServiceName: Name of deployed function + ServiceName string `json:"serviceName" mapstructure:"serviceName"` +} + +// Validate implements basic validation for this model +func (m ScaleServiceRequest) Validate() error { + return validation.Errors{ + "replicas": validation.Validate( + m.Replicas, validation.Min(int64(0)), + ), + }.Filter() +} + +// GetReplicas returns the Replicas property +func (m ScaleServiceRequest) GetReplicas() int64 { + return m.Replicas +} + +// SetReplicas sets the Replicas property +func (m *ScaleServiceRequest) SetReplicas(val int64) { + m.Replicas = val +} + +// GetServiceName returns the ServiceName property +func (m ScaleServiceRequest) GetServiceName() string { + return m.ServiceName +} + +// SetServiceName sets the ServiceName property +func (m *ScaleServiceRequest) SetServiceName(val string) { + m.ServiceName = val +} diff --git a/gateway/models/model_secret.go b/gateway/models/model_secret.go new file mode 100644 index 00000000..398ec735 --- /dev/null +++ b/gateway/models/model_secret.go @@ -0,0 +1,75 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" + "github.com/go-ozzo/ozzo-validation/v4/is" +) + +// Secret is an object. +type Secret struct { + // Name: Name of secret + Name string `json:"name" mapstructure:"name"` + // Namespace: Namespace of secret + Namespace string `json:"namespace,omitempty" mapstructure:"namespace,omitempty"` + // RawValue: Value of secret in base64. + // + // This can be used to provide raw binary data when the `value` field is omitted. + RawValue string `json:"rawValue,omitempty" mapstructure:"rawValue,omitempty"` + // Value: Value of secret in plain-text + Value string `json:"value,omitempty" mapstructure:"value,omitempty"` +} + +// Validate implements basic validation for this model +func (m Secret) Validate() error { + return validation.Errors{ + "rawValue": validation.Validate( + m.RawValue, is.Base64, + ), + }.Filter() +} + +// GetName returns the Name property +func (m Secret) GetName() string { + return m.Name +} + +// SetName sets the Name property +func (m *Secret) SetName(val string) { + m.Name = val +} + +// GetNamespace returns the Namespace property +func (m Secret) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *Secret) SetNamespace(val string) { + m.Namespace = val +} + +// GetRawValue returns the RawValue property +func (m Secret) GetRawValue() string { + return m.RawValue +} + +// SetRawValue sets the RawValue property +func (m *Secret) SetRawValue(val string) { + m.RawValue = val +} + +// GetValue returns the Value property +func (m Secret) GetValue() string { + return m.Value +} + +// SetValue sets the Value property +func (m *Secret) SetValue(val string) { + m.Value = val +} diff --git a/gateway/models/model_secret_description.go b/gateway/models/model_secret_description.go new file mode 100644 index 00000000..eb64a025 --- /dev/null +++ b/gateway/models/model_secret_description.go @@ -0,0 +1,44 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// SecretDescription is an object. +type SecretDescription struct { + // Name: Name of secret + Name string `json:"name" mapstructure:"name"` + // Namespace: Namespace of secret + Namespace string `json:"namespace,omitempty" mapstructure:"namespace,omitempty"` +} + +// Validate implements basic validation for this model +func (m SecretDescription) Validate() error { + return validation.Errors{}.Filter() +} + +// GetName returns the Name property +func (m SecretDescription) GetName() string { + return m.Name +} + +// SetName sets the Name property +func (m *SecretDescription) SetName(val string) { + m.Name = val +} + +// GetNamespace returns the Namespace property +func (m SecretDescription) GetNamespace() string { + return m.Namespace +} + +// SetNamespace sets the Namespace property +func (m *SecretDescription) SetNamespace(val string) { + m.Namespace = val +} diff --git a/gateway/models/model_secret_values.go b/gateway/models/model_secret_values.go new file mode 100644 index 00000000..25defd04 --- /dev/null +++ b/gateway/models/model_secret_values.go @@ -0,0 +1,51 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" + "github.com/go-ozzo/ozzo-validation/v4/is" +) + +// SecretValues is an object. +type SecretValues struct { + // RawValue: Value of secret in base64. + // + // This can be used to provide raw binary data when the `value` field is omitted. + RawValue string `json:"rawValue,omitempty" mapstructure:"rawValue,omitempty"` + // Value: Value of secret in plain-text + Value string `json:"value,omitempty" mapstructure:"value,omitempty"` +} + +// Validate implements basic validation for this model +func (m SecretValues) Validate() error { + return validation.Errors{ + "rawValue": validation.Validate( + m.RawValue, is.Base64, + ), + }.Filter() +} + +// GetRawValue returns the RawValue property +func (m SecretValues) GetRawValue() string { + return m.RawValue +} + +// SetRawValue sets the RawValue property +func (m *SecretValues) SetRawValue(val string) { + m.RawValue = val +} + +// GetValue returns the Value property +func (m SecretValues) GetValue() string { + return m.Value +} + +// SetValue sets the Value property +func (m *SecretValues) SetValue(val string) { + m.Value = val +} diff --git a/gateway/models/model_version_info.go b/gateway/models/model_version_info.go new file mode 100644 index 00000000..0c57666e --- /dev/null +++ b/gateway/models/model_version_info.go @@ -0,0 +1,56 @@ +// This file is auto-generated, DO NOT EDIT. +// +// Source: +// +// Title: OpenFaaS API Gateway +// Version: 0.8.12 +package models + +import ( + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +// VersionInfo is an object. +type VersionInfo struct { + // CommitMessage: + CommitMessage string `json:"commit_message,omitempty" mapstructure:"commit_message,omitempty"` + // Release: + Release string `json:"release" mapstructure:"release"` + // Sha: + Sha string `json:"sha" mapstructure:"sha"` +} + +// Validate implements basic validation for this model +func (m VersionInfo) Validate() error { + return validation.Errors{}.Filter() +} + +// GetCommitMessage returns the CommitMessage property +func (m VersionInfo) GetCommitMessage() string { + return m.CommitMessage +} + +// SetCommitMessage sets the CommitMessage property +func (m *VersionInfo) SetCommitMessage(val string) { + m.CommitMessage = val +} + +// GetRelease returns the Release property +func (m VersionInfo) GetRelease() string { + return m.Release +} + +// SetRelease sets the Release property +func (m *VersionInfo) SetRelease(val string) { + m.Release = val +} + +// GetSha returns the Sha property +func (m VersionInfo) GetSha() string { + return m.Sha +} + +// SetSha sets the Sha property +func (m *VersionInfo) SetSha(val string) { + m.Sha = val +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/.gitignore b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/.gitignore new file mode 100644 index 00000000..ef6e33fc --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/.gitignore @@ -0,0 +1,28 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Idea Directory +.idea + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +.DS_Store diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/.travis.yml b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/.travis.yml new file mode 100644 index 00000000..28febbda --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/.travis.yml @@ -0,0 +1,17 @@ +dist: bionic + +language: go + +go: + - 1.13.x + +install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go get golang.org/x/lint/golint + +script: + - test -z "`gofmt -l -d .`" + - test -z "`golint ./...`" + - go test -v -covermode=count -coverprofile=coverage.out + - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/LICENSE b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/LICENSE new file mode 100644 index 00000000..d235be9c --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/LICENSE @@ -0,0 +1,17 @@ +The MIT License (MIT) +Copyright (c) 2016, Qiang Xue + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/README.md b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/README.md new file mode 100644 index 00000000..6c14bbf7 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/README.md @@ -0,0 +1,703 @@ +# ozzo-validation + +[![GoDoc](https://godoc.org/github.com/go-ozzo/ozzo-validation?status.png)](http://godoc.org/github.com/go-ozzo/ozzo-validation) +[![Build Status](https://travis-ci.org/go-ozzo/ozzo-validation.svg?branch=master)](https://travis-ci.org/go-ozzo/ozzo-validation) +[![Coverage Status](https://coveralls.io/repos/github/go-ozzo/ozzo-validation/badge.svg?branch=master)](https://coveralls.io/github/go-ozzo/ozzo-validation?branch=master) +[![Go Report](https://goreportcard.com/badge/github.com/go-ozzo/ozzo-validation)](https://goreportcard.com/report/github.com/go-ozzo/ozzo-validation) + +## Description + +ozzo-validation is a Go package that provides configurable and extensible data validation capabilities. +It has the following features: + +* use normal programming constructs rather than error-prone struct tags to specify how data should be validated. +* can validate data of different types, e.g., structs, strings, byte slices, slices, maps, arrays. +* can validate custom data types as long as they implement the `Validatable` interface. +* can validate data types that implement the `sql.Valuer` interface (e.g. `sql.NullString`). +* customizable and well-formatted validation errors. +* error code and message translation support. +* provide a rich set of validation rules right out of box. +* extremely easy to create and use custom validation rules. + +For an example on how this library is used in an application, please refer to [go-rest-api](https://github.com/qiangxue/go-rest-api) which is a starter kit for building RESTful APIs in Go. + +## Requirements + +Go 1.13 or above. + + +## Getting Started + +The ozzo-validation package mainly includes a set of validation rules and two validation methods. You use +validation rules to describe how a value should be considered valid, and you call either `validation.Validate()` +or `validation.ValidateStruct()` to validate the value. + + +### Installation + +Run the following command to install the package: + +``` +go get github.com/go-ozzo/ozzo-validation +``` + +### Validating a Simple Value + +For a simple value, such as a string or an integer, you may use `validation.Validate()` to validate it. For example, + +```go +package main + +import ( + "fmt" + + "github.com/go-ozzo/ozzo-validation/v4" + "github.com/go-ozzo/ozzo-validation/v4/is" +) + +func main() { + data := "example" + err := validation.Validate(data, + validation.Required, // not empty + validation.Length(5, 100), // length between 5 and 100 + is.URL, // is a valid URL + ) + fmt.Println(err) + // Output: + // must be a valid URL +} +``` + +The method `validation.Validate()` will run through the rules in the order that they are listed. If a rule fails +the validation, the method will return the corresponding error and skip the rest of the rules. The method will +return nil if the value passes all validation rules. + + +### Validating a Struct + +For a struct value, you usually want to check if its fields are valid. For example, in a RESTful application, you +may unmarshal the request payload into a struct and then validate the struct fields. If one or multiple fields +are invalid, you may want to get an error describing which fields are invalid. You can use `validation.ValidateStruct()` +to achieve this purpose. A single struct can have rules for multiple fields, and a field can be associated with multiple +rules. For example, + +```go +type Address struct { + Street string + City string + State string + Zip string +} + +func (a Address) Validate() error { + return validation.ValidateStruct(&a, + // Street cannot be empty, and the length must between 5 and 50 + validation.Field(&a.Street, validation.Required, validation.Length(5, 50)), + // City cannot be empty, and the length must between 5 and 50 + validation.Field(&a.City, validation.Required, validation.Length(5, 50)), + // State cannot be empty, and must be a string consisting of two letters in upper case + validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))), + // State cannot be empty, and must be a string consisting of five digits + validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), + ) +} + +a := Address{ + Street: "123", + City: "Unknown", + State: "Virginia", + Zip: "12345", +} + +err := a.Validate() +fmt.Println(err) +// Output: +// Street: the length must be between 5 and 50; State: must be in a valid format. +``` + +Note that when calling `validation.ValidateStruct` to validate a struct, you should pass to the method a pointer +to the struct instead of the struct itself. Similarly, when calling `validation.Field` to specify the rules +for a struct field, you should use a pointer to the struct field. + +When the struct validation is performed, the fields are validated in the order they are specified in `ValidateStruct`. +And when each field is validated, its rules are also evaluated in the order they are associated with the field. +If a rule fails, an error is recorded for that field, and the validation will continue with the next field. + + +### Validating a Map + +Sometimes you might need to work with dynamic data stored in maps rather than a typed model. You can use `validation.Map()` +in this situation. A single map can have rules for multiple keys, and a key can be associated with multiple +rules. For example, + +```go +c := map[string]interface{}{ + "Name": "Qiang Xue", + "Email": "q", + "Address": map[string]interface{}{ + "Street": "123", + "City": "Unknown", + "State": "Virginia", + "Zip": "12345", + }, +} + +err := validation.Validate(c, + validation.Map( + // Name cannot be empty, and the length must be between 5 and 20. + validation.Key("Name", validation.Required, validation.Length(5, 20)), + // Email cannot be empty and should be in a valid email format. + validation.Key("Email", validation.Required, is.Email), + // Validate Address using its own validation rules + validation.Key("Address", validation.Map( + // Street cannot be empty, and the length must between 5 and 50 + validation.Key("Street", validation.Required, validation.Length(5, 50)), + // City cannot be empty, and the length must between 5 and 50 + validation.Key("City", validation.Required, validation.Length(5, 50)), + // State cannot be empty, and must be a string consisting of two letters in upper case + validation.Key("State", validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))), + // State cannot be empty, and must be a string consisting of five digits + validation.Key("Zip", validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), + )), + ), +) +fmt.Println(err) +// Output: +// Address: (State: must be in a valid format; Street: the length must be between 5 and 50.); Email: must be a valid email address. +``` + +When the map validation is performed, the keys are validated in the order they are specified in `Map`. +And when each key is validated, its rules are also evaluated in the order they are associated with the key. +If a rule fails, an error is recorded for that key, and the validation will continue with the next key. + + +### Validation Errors + +The `validation.ValidateStruct` method returns validation errors found in struct fields in terms of `validation.Errors` +which is a map of fields and their corresponding errors. Nil is returned if validation passes. + +By default, `validation.Errors` uses the struct tags named `json` to determine what names should be used to +represent the invalid fields. The type also implements the `json.Marshaler` interface so that it can be marshaled +into a proper JSON object. For example, + +```go +type Address struct { + Street string `json:"street"` + City string `json:"city"` + State string `json:"state"` + Zip string `json:"zip"` +} + +// ...perform validation here... + +err := a.Validate() +b, _ := json.Marshal(err) +fmt.Println(string(b)) +// Output: +// {"street":"the length must be between 5 and 50","state":"must be in a valid format"} +``` + +You may modify `validation.ErrorTag` to use a different struct tag name. + +If you do not like the magic that `ValidateStruct` determines error keys based on struct field names or corresponding +tag values, you may use the following alternative approach: + +```go +c := Customer{ + Name: "Qiang Xue", + Email: "q", + Address: Address{ + State: "Virginia", + }, +} + +err := validation.Errors{ + "name": validation.Validate(c.Name, validation.Required, validation.Length(5, 20)), + "email": validation.Validate(c.Name, validation.Required, is.Email), + "zip": validation.Validate(c.Address.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), +}.Filter() +fmt.Println(err) +// Output: +// email: must be a valid email address; zip: cannot be blank. +``` + +In the above example, we build a `validation.Errors` by a list of names and the corresponding validation results. +At the end we call `Errors.Filter()` to remove from `Errors` all nils which correspond to those successful validation +results. The method will return nil if `Errors` is empty. + +The above approach is very flexible as it allows you to freely build up your validation error structure. You can use +it to validate both struct and non-struct values. Compared to using `ValidateStruct` to validate a struct, +it has the drawback that you have to redundantly specify the error keys while `ValidateStruct` can automatically +find them out. + + +### Internal Errors + +Internal errors are different from validation errors in that internal errors are caused by malfunctioning code (e.g. +a validator making a remote call to validate some data when the remote service is down) rather +than the data being validated. When an internal error happens during data validation, you may allow the user to resubmit +the same data to perform validation again, hoping the program resumes functioning. On the other hand, if data validation +fails due to data error, the user should generally not resubmit the same data again. + +To differentiate internal errors from validation errors, when an internal error occurs in a validator, wrap it +into `validation.InternalError` by calling `validation.NewInternalError()`. The user of the validator can then check +if a returned error is an internal error or not. For example, + +```go +if err := a.Validate(); err != nil { + if e, ok := err.(validation.InternalError); ok { + // an internal error happened + fmt.Println(e.InternalError()) + } +} +``` + + +## Validatable Types + +A type is validatable if it implements the `validation.Validatable` interface. + +When `validation.Validate` is used to validate a validatable value, if it does not find any error with the +given validation rules, it will further call the value's `Validate()` method. + +Similarly, when `validation.ValidateStruct` is validating a struct field whose type is validatable, it will call +the field's `Validate` method after it passes the listed rules. + +> Note: When implementing `validation.Validatable`, do not call `validation.Validate()` to validate the value in its +> original type because this will cause infinite loops. For example, if you define a new type `MyString` as `string` +> and implement `validation.Validatable` for `MyString`, within the `Validate()` function you should cast the value +> to `string` first before calling `validation.Validate()` to validate it. + +In the following example, the `Address` field of `Customer` is validatable because `Address` implements +`validation.Validatable`. Therefore, when validating a `Customer` struct with `validation.ValidateStruct`, +validation will "dive" into the `Address` field. + +```go +type Customer struct { + Name string + Gender string + Email string + Address Address +} + +func (c Customer) Validate() error { + return validation.ValidateStruct(&c, + // Name cannot be empty, and the length must be between 5 and 20. + validation.Field(&c.Name, validation.Required, validation.Length(5, 20)), + // Gender is optional, and should be either "Female" or "Male". + validation.Field(&c.Gender, validation.In("Female", "Male")), + // Email cannot be empty and should be in a valid email format. + validation.Field(&c.Email, validation.Required, is.Email), + // Validate Address using its own validation rules + validation.Field(&c.Address), + ) +} + +c := Customer{ + Name: "Qiang Xue", + Email: "q", + Address: Address{ + Street: "123 Main Street", + City: "Unknown", + State: "Virginia", + Zip: "12345", + }, +} + +err := c.Validate() +fmt.Println(err) +// Output: +// Address: (State: must be in a valid format.); Email: must be a valid email address. +``` + +Sometimes, you may want to skip the invocation of a type's `Validate` method. To do so, simply associate +a `validation.Skip` rule with the value being validated. + +### Maps/Slices/Arrays of Validatables + +When validating an iterable (map, slice, or array), whose element type implements the `validation.Validatable` interface, +the `validation.Validate` method will call the `Validate` method of every non-nil element. +The validation errors of the elements will be returned as `validation.Errors` which maps the keys of the +invalid elements to their corresponding validation errors. For example, + +```go +addresses := []Address{ + Address{State: "MD", Zip: "12345"}, + Address{Street: "123 Main St", City: "Vienna", State: "VA", Zip: "12345"}, + Address{City: "Unknown", State: "NC", Zip: "123"}, +} +err := validation.Validate(addresses) +fmt.Println(err) +// Output: +// 0: (City: cannot be blank; Street: cannot be blank.); 2: (Street: cannot be blank; Zip: must be in a valid format.). +``` + +When using `validation.ValidateStruct` to validate a struct, the above validation procedure also applies to those struct +fields which are map/slices/arrays of validatables. + +#### Each + +The `Each` validation rule allows you to apply a set of rules to each element of an array, slice, or map. + +```go +type Customer struct { + Name string + Emails []string +} + +func (c Customer) Validate() error { + return validation.ValidateStruct(&c, + // Name cannot be empty, and the length must be between 5 and 20. + validation.Field(&c.Name, validation.Required, validation.Length(5, 20)), + // Emails are optional, but if given must be valid. + validation.Field(&c.Emails, validation.Each(is.Email)), + ) +} + +c := Customer{ + Name: "Qiang Xue", + Emails: []Email{ + "valid@example.com", + "invalid", + }, +} + +err := c.Validate() +fmt.Println(err) +// Output: +// Emails: (1: must be a valid email address.). +``` + +### Pointers + +When a value being validated is a pointer, most validation rules will validate the actual value pointed to by the pointer. +If the pointer is nil, these rules will skip the validation. + +An exception is the `validation.Required` and `validation.NotNil` rules. When a pointer is nil, they +will report a validation error. + + +### Types Implementing `sql.Valuer` + +If a data type implements the `sql.Valuer` interface (e.g. `sql.NullString`), the built-in validation rules will handle +it properly. In particular, when a rule is validating such data, it will call the `Value()` method and validate +the returned value instead. + + +### Required vs. Not Nil + +When validating input values, there are two different scenarios about checking if input values are provided or not. + +In the first scenario, an input value is considered missing if it is not entered or it is entered as a zero value +(e.g. an empty string, a zero integer). You can use the `validation.Required` rule in this case. + +In the second scenario, an input value is considered missing only if it is not entered. A pointer field is usually +used in this case so that you can detect if a value is entered or not by checking if the pointer is nil or not. +You can use the `validation.NotNil` rule to ensure a value is entered (even if it is a zero value). + + +### Embedded Structs + +The `validation.ValidateStruct` method will properly validate a struct that contains embedded structs. In particular, +the fields of an embedded struct are treated as if they belong directly to the containing struct. For example, + +```go +type Employee struct { + Name string +} + +type Manager struct { + Employee + Level int +} + +m := Manager{} +err := validation.ValidateStruct(&m, + validation.Field(&m.Name, validation.Required), + validation.Field(&m.Level, validation.Required), +) +fmt.Println(err) +// Output: +// Level: cannot be blank; Name: cannot be blank. +``` + +In the above code, we use `&m.Name` to specify the validation of the `Name` field of the embedded struct `Employee`. +And the validation error uses `Name` as the key for the error associated with the `Name` field as if `Name` a field +directly belonging to `Manager`. + +If `Employee` implements the `validation.Validatable` interface, we can also use the following code to validate +`Manager`, which generates the same validation result: + +```go +func (e Employee) Validate() error { + return validation.ValidateStruct(&e, + validation.Field(&e.Name, validation.Required), + ) +} + +err := validation.ValidateStruct(&m, + validation.Field(&m.Employee), + validation.Field(&m.Level, validation.Required), +) +fmt.Println(err) +// Output: +// Level: cannot be blank; Name: cannot be blank. +``` + + +### Conditional Validation + +Sometimes, we may want to validate a value only when certain condition is met. For example, we want to ensure the +`unit` struct field is not empty only when the `quantity` field is not empty; or we may want to ensure either `email` +or `phone` is provided. The so-called conditional validation can be achieved with the help of `validation.When`. +The following code implements the aforementioned examples: + +```go +result := validation.ValidateStruct(&a, + validation.Field(&a.Unit, validation.When(a.Quantity != "", validation.Required).Else(validation.Nil)), + validation.Field(&a.Phone, validation.When(a.Email == "", validation.Required.Error('Either phone or Email is required.')), + validation.Field(&a.Email, validation.When(a.Phone == "", validation.Required.Error('Either phone or Email is required.')), +) +``` + +Note that `validation.When` and `validation.When.Else` can take a list of validation rules. These rules will be executed only when the condition is true (When) or false (Else). + +The above code can also be simplified using the shortcut `validation.Required.When`: + +```go +result := validation.ValidateStruct(&a, + validation.Field(&a.Unit, validation.Required.When(a.Quantity != ""), validation.Nil.When(a.Quantity == "")), + validation.Field(&a.Phone, validation.Required.When(a.Email == "").Error('Either phone or Email is required.')), + validation.Field(&a.Email, validation.Required.When(a.Phone == "").Error('Either phone or Email is required.')), +) +``` + +### Customizing Error Messages + +All built-in validation rules allow you to customize their error messages. To do so, simply call the `Error()` method +of the rules. For example, + +```go +data := "2123" +err := validation.Validate(data, + validation.Required.Error("is required"), + validation.Match(regexp.MustCompile("^[0-9]{5}$")).Error("must be a string with five digits"), +) +fmt.Println(err) +// Output: +// must be a string with five digits +``` + +You can also customize the pre-defined error(s) of a built-in rule such that the customization applies to *every* +instance of the rule. For example, the `Required` rule uses the pre-defined error `ErrRequired`. You can customize it +during the application initialization: +```go +validation.ErrRequired = validation.ErrRequired.SetMessage("the value is required") +``` + +### Error Code and Message Translation + +The errors returned by the validation rules implement the `Error` interface which contains the `Code()` method +to provide the error code information. While the message of a validation error is often customized, the code is immutable. +You can use error code to programmatically check a validation error or look for the translation of the corresponding message. + +If you are developing your own validation rules, you can use `validation.NewError()` to create a validation error which +implements the aforementioned `Error` interface. + +## Creating Custom Rules + +Creating a custom rule is as simple as implementing the `validation.Rule` interface. The interface contains a single +method as shown below, which should validate the value and return the validation error, if any: + +```go +// Validate validates a value and returns an error if validation fails. +Validate(value interface{}) error +``` + +If you already have a function with the same signature as shown above, you can call `validation.By()` to turn +it into a validation rule. For example, + +```go +func checkAbc(value interface{}) error { + s, _ := value.(string) + if s != "abc" { + return errors.New("must be abc") + } + return nil +} + +err := validation.Validate("xyz", validation.By(checkAbc)) +fmt.Println(err) +// Output: must be abc +``` + +If your validation function takes additional parameters, you can use the following closure trick: + +```go +func stringEquals(str string) validation.RuleFunc { + return func(value interface{}) error { + s, _ := value.(string) + if s != str { + return errors.New("unexpected string") + } + return nil + } +} + +err := validation.Validate("xyz", validation.By(stringEquals("abc"))) +fmt.Println(err) +// Output: unexpected string +``` + + +### Rule Groups + +When a combination of several rules are used in multiple places, you may use the following trick to create a +rule group so that your code is more maintainable. + +```go +var NameRule = []validation.Rule{ + validation.Required, + validation.Length(5, 20), +} + +type User struct { + FirstName string + LastName string +} + +func (u User) Validate() error { + return validation.ValidateStruct(&u, + validation.Field(&u.FirstName, NameRule...), + validation.Field(&u.LastName, NameRule...), + ) +} +``` + +In the above example, we create a rule group `NameRule` which consists of two validation rules. We then use this rule +group to validate both `FirstName` and `LastName`. + + +## Context-aware Validation + +While most validation rules are self-contained, some rules may depend dynamically on a context. A rule may implement the +`validation.RuleWithContext` interface to support the so-called context-aware validation. + +To validate an arbitrary value with a context, call `validation.ValidateWithContext()`. The `context.Conext` parameter +will be passed along to those rules that implement `validation.RuleWithContext`. + +To validate the fields of a struct with a context, call `validation.ValidateStructWithContext()`. + +You can define a context-aware rule from scratch by implementing both `validation.Rule` and `validation.RuleWithContext`. +You can also use `validation.WithContext()` to turn a function into a context-aware rule. For example, + + +```go +rule := validation.WithContext(func(ctx context.Context, value interface{}) error { + if ctx.Value("secret") == value.(string) { + return nil + } + return errors.New("value incorrect") +}) +value := "xyz" +ctx := context.WithValue(context.Background(), "secret", "example") +err := validation.ValidateWithContext(ctx, value, rule) +fmt.Println(err) +// Output: value incorrect +``` + +When performing context-aware validation, if a rule does not implement `validation.RuleWithContext`, its +`validation.Rule` will be used instead. + + +## Built-in Validation Rules + +The following rules are provided in the `validation` package: + +* `In(...interface{})`: checks if a value can be found in the given list of values. +* `NotIn(...interface{})`: checks if a value is NOT among the given list of values. +* `Length(min, max int)`: checks if the length of a value is within the specified range. + This rule should only be used for validating strings, slices, maps, and arrays. +* `RuneLength(min, max int)`: checks if the length of a string is within the specified range. + This rule is similar as `Length` except that when the value being validated is a string, it checks + its rune length instead of byte length. +* `Min(min interface{})` and `Max(max interface{})`: checks if a value is within the specified range. + These two rules should only be used for validating int, uint, float and time.Time types. +* `Match(*regexp.Regexp)`: checks if a value matches the specified regular expression. + This rule should only be used for strings and byte slices. +* `Date(layout string)`: checks if a string value is a date whose format is specified by the layout. + By calling `Min()` and/or `Max()`, you can check additionally if the date is within the specified range. +* `Required`: checks if a value is not empty (neither nil nor zero). +* `NotNil`: checks if a pointer value is not nil. Non-pointer values are considered valid. +* `NilOrNotEmpty`: checks if a value is a nil pointer or a non-empty value. This differs from `Required` in that it treats a nil pointer as valid. +* `Nil`: checks if a value is a nil pointer. +* `Empty`: checks if a value is empty. nil pointers are considered valid. +* `Skip`: this is a special rule used to indicate that all rules following it should be skipped (including the nested ones). +* `MultipleOf`: checks if the value is a multiple of the specified range. +* `Each(rules ...Rule)`: checks the elements within an iterable (map/slice/array) with other rules. +* `When(condition, rules ...Rule)`: validates with the specified rules only when the condition is true. +* `Else(rules ...Rule)`: must be used with `When(condition, rules ...Rule)`, validates with the specified rules only when the condition is false. + +The `is` sub-package provides a list of commonly used string validation rules that can be used to check if the format +of a value satisfies certain requirements. Note that these rules only handle strings and byte slices and if a string + or byte slice is empty, it is considered valid. You may use a `Required` rule to ensure a value is not empty. +Below is the whole list of the rules provided by the `is` package: + +* `Email`: validates if a string is an email or not. It also checks if the MX record exists for the email domain. +* `EmailFormat`: validates if a string is an email or not. It does NOT check the existence of the MX record. +* `URL`: validates if a string is a valid URL +* `RequestURL`: validates if a string is a valid request URL +* `RequestURI`: validates if a string is a valid request URI +* `Alpha`: validates if a string contains English letters only (a-zA-Z) +* `Digit`: validates if a string contains digits only (0-9) +* `Alphanumeric`: validates if a string contains English letters and digits only (a-zA-Z0-9) +* `UTFLetter`: validates if a string contains unicode letters only +* `UTFDigit`: validates if a string contains unicode decimal digits only +* `UTFLetterNumeric`: validates if a string contains unicode letters and numbers only +* `UTFNumeric`: validates if a string contains unicode number characters (category N) only +* `LowerCase`: validates if a string contains lower case unicode letters only +* `UpperCase`: validates if a string contains upper case unicode letters only +* `Hexadecimal`: validates if a string is a valid hexadecimal number +* `HexColor`: validates if a string is a valid hexadecimal color code +* `RGBColor`: validates if a string is a valid RGB color in the form of rgb(R, G, B) +* `Int`: validates if a string is a valid integer number +* `Float`: validates if a string is a floating point number +* `UUIDv3`: validates if a string is a valid version 3 UUID +* `UUIDv4`: validates if a string is a valid version 4 UUID +* `UUIDv5`: validates if a string is a valid version 5 UUID +* `UUID`: validates if a string is a valid UUID +* `CreditCard`: validates if a string is a valid credit card number +* `ISBN10`: validates if a string is an ISBN version 10 +* `ISBN13`: validates if a string is an ISBN version 13 +* `ISBN`: validates if a string is an ISBN (either version 10 or 13) +* `JSON`: validates if a string is in valid JSON format +* `ASCII`: validates if a string contains ASCII characters only +* `PrintableASCII`: validates if a string contains printable ASCII characters only +* `Multibyte`: validates if a string contains multibyte characters +* `FullWidth`: validates if a string contains full-width characters +* `HalfWidth`: validates if a string contains half-width characters +* `VariableWidth`: validates if a string contains both full-width and half-width characters +* `Base64`: validates if a string is encoded in Base64 +* `DataURI`: validates if a string is a valid base64-encoded data URI +* `E164`: validates if a string is a valid E164 phone number (+19251232233) +* `CountryCode2`: validates if a string is a valid ISO3166 Alpha 2 country code +* `CountryCode3`: validates if a string is a valid ISO3166 Alpha 3 country code +* `DialString`: validates if a string is a valid dial string that can be passed to Dial() +* `MAC`: validates if a string is a MAC address +* `IP`: validates if a string is a valid IP address (either version 4 or 6) +* `IPv4`: validates if a string is a valid version 4 IP address +* `IPv6`: validates if a string is a valid version 6 IP address +* `Subdomain`: validates if a string is valid subdomain +* `Domain`: validates if a string is valid domain +* `DNSName`: validates if a string is valid DNS name +* `Host`: validates if a string is a valid IP (both v4 and v6) or a valid DNS name +* `Port`: validates if a string is a valid port number +* `MongoID`: validates if a string is a valid Mongo ID +* `Latitude`: validates if a string is a valid latitude +* `Longitude`: validates if a string is a valid longitude +* `SSN`: validates if a string is a social security number (SSN) +* `Semver`: validates if a string is a valid semantic version + +## Credits + +The `is` sub-package wraps the excellent validators provided by the [govalidator](https://github.com/asaskevich/govalidator) package. diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/UPGRADE.md b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/UPGRADE.md new file mode 100644 index 00000000..73bd222a --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/UPGRADE.md @@ -0,0 +1,64 @@ +# Upgrade Instructions + +## Upgrade from 3.x to 4.x + +If you are customizing the error messages of the following built-in validation rules, you may need to +change the parameter placeholders from `%v` to the Go template variable placeholders. +* `Length`: use `{{.min}}` and `{{.max}}` in the error message to refer to the minimum and maximum lengths. +* `Min`: use `{{.threshold}}` in the error message to refer to the lower bound. +* `Max`: use `{{.threshold}}` in the error message to refer to the upper bound +* `MultipleOf`: use `{{.base}}` in the error message to refer to the base of the multiples. + +For example, + ```go +// 3.x +lengthRule := validation.Length(2,10).Error("the length must be between %v and %v") + +// 4.x +lengthRule := validation.Length(2,10).Error("the length must be between {{.min}} and {{.max}}") +``` + +## Upgrade from 2.x to 3.x + +* Instead of using `StructRules` to define struct validation rules, use `ValidateStruct()` to declare and perform + struct validation. The following code snippet shows how to modify your code: +```go +// 2.x usage +err := validation.StructRules{}. + Add("Street", validation.Required, validation.Length(5, 50)). + Add("City", validation.Required, validation.Length(5, 50)). + Add("State", validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))). + Add("Zip", validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))). + Validate(a) + +// 3.x usage +err := validation.ValidateStruct(&a, + validation.Field(&a.Street, validation.Required, validation.Length(5, 50)), + validation.Field(&a.City, validation.Required, validation.Length(5, 50)), + validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))), + validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), +) +``` + +* Instead of using `Rules` to declare a rule list and use it to validate a value, call `Validate()` with the rules directly. +```go +data := "example" + +// 2.x usage +rules := validation.Rules{ + validation.Required, + validation.Length(5, 100), + is.URL, +} +err := rules.Validate(data) + +// 3.x usage +err := validation.Validate(data, + validation.Required, + validation.Length(5, 100), + is.URL, +) +``` + +* The default struct tags used for determining error keys is changed from `validation` to `json`. You may modify + `validation.ErrorTag` to change it back. \ No newline at end of file diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/absent.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/absent.go new file mode 100644 index 00000000..91fefe13 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/absent.go @@ -0,0 +1,67 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +var ( + // ErrNil is the error that returns when a value is not nil. + ErrNil = NewError("validation_nil", "must be blank") + // ErrEmpty is the error that returns when a not nil value is not empty. + ErrEmpty = NewError("validation_empty", "must be blank") +) + +// Nil is a validation rule that checks if a value is nil. +// It is the opposite of NotNil rule +var Nil = absentRule{condition: true, skipNil: false} + +// Empty checks if a not nil value is empty. +var Empty = absentRule{condition: true, skipNil: true} + +type absentRule struct { + condition bool + err Error + skipNil bool +} + +// Validate checks if the given value is valid or not. +func (r absentRule) Validate(value interface{}) error { + if r.condition { + value, isNil := Indirect(value) + if !r.skipNil && !isNil || r.skipNil && !isNil && !IsEmpty(value) { + if r.err != nil { + return r.err + } + if r.skipNil { + return ErrEmpty + } + return ErrNil + } + } + return nil +} + +// When sets the condition that determines if the validation should be performed. +func (r absentRule) When(condition bool) absentRule { + r.condition = condition + return r +} + +// Error sets the error message for the rule. +func (r absentRule) Error(message string) absentRule { + if r.err == nil { + if r.skipNil { + r.err = ErrEmpty + } else { + r.err = ErrNil + } + } + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r absentRule) ErrorObject(err Error) absentRule { + r.err = err + return r +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/date.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/date.go new file mode 100644 index 00000000..31da0e32 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/date.go @@ -0,0 +1,102 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "time" +) + +var ( + // ErrDateInvalid is the error that returns in case of an invalid date. + ErrDateInvalid = NewError("validation_date_invalid", "must be a valid date") + // ErrDateOutOfRange is the error that returns in case of an invalid date. + ErrDateOutOfRange = NewError("validation_date_out_of_range", "the date is out of range") +) + +// DateRule is a validation rule that validates date/time string values. +type DateRule struct { + layout string + min, max time.Time + err, rangeErr Error +} + +// Date returns a validation rule that checks if a string value is in a format that can be parsed into a date. +// The format of the date should be specified as the layout parameter which accepts the same value as that for time.Parse. +// For example, +// validation.Date(time.ANSIC) +// validation.Date("02 Jan 06 15:04 MST") +// validation.Date("2006-01-02") +// +// By calling Min() and/or Max(), you can let the Date rule to check if a parsed date value is within +// the specified date range. +// +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func Date(layout string) DateRule { + return DateRule{ + layout: layout, + err: ErrDateInvalid, + rangeErr: ErrDateOutOfRange, + } +} + +// Error sets the error message that is used when the value being validated is not a valid date. +func (r DateRule) Error(message string) DateRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct that is used when the value being validated is not a valid date.. +func (r DateRule) ErrorObject(err Error) DateRule { + r.err = err + return r +} + +// RangeError sets the error message that is used when the value being validated is out of the specified Min/Max date range. +func (r DateRule) RangeError(message string) DateRule { + r.rangeErr = r.rangeErr.SetMessage(message) + return r +} + +// RangeErrorObject sets the error struct that is used when the value being validated is out of the specified Min/Max date range. +func (r DateRule) RangeErrorObject(err Error) DateRule { + r.rangeErr = err + return r +} + +// Min sets the minimum date range. A zero value means skipping the minimum range validation. +func (r DateRule) Min(min time.Time) DateRule { + r.min = min + return r +} + +// Max sets the maximum date range. A zero value means skipping the maximum range validation. +func (r DateRule) Max(max time.Time) DateRule { + r.max = max + return r +} + +// Validate checks if the given value is a valid date. +func (r DateRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + str, err := EnsureString(value) + if err != nil { + return err + } + + date, err := time.Parse(r.layout, str) + if err != nil { + return r.err + } + + if !r.min.IsZero() && r.min.After(date) || !r.max.IsZero() && date.After(r.max) { + return r.rangeErr + } + + return nil +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/each.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/each.go new file mode 100644 index 00000000..2cc72534 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/each.go @@ -0,0 +1,97 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "context" + "errors" + "reflect" + "strconv" +) + +// Each returns a validation rule that loops through an iterable (map, slice or array) +// and validates each value inside with the provided rules. +// An empty iterable is considered valid. Use the Required rule to make sure the iterable is not empty. +func Each(rules ...Rule) EachRule { + return EachRule{ + rules: rules, + } +} + +// EachRule is a validation rule that validates elements in a map/slice/array using the specified list of rules. +type EachRule struct { + rules []Rule +} + +// Validate loops through the given iterable and calls the Ozzo Validate() method for each value. +func (r EachRule) Validate(value interface{}) error { + return r.ValidateWithContext(nil, value) +} + +// ValidateWithContext loops through the given iterable and calls the Ozzo ValidateWithContext() method for each value. +func (r EachRule) ValidateWithContext(ctx context.Context, value interface{}) error { + errs := Errors{} + + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Map: + for _, k := range v.MapKeys() { + val := r.getInterface(v.MapIndex(k)) + var err error + if ctx == nil { + err = Validate(val, r.rules...) + } else { + err = ValidateWithContext(ctx, val, r.rules...) + } + if err != nil { + errs[r.getString(k)] = err + } + } + case reflect.Slice, reflect.Array: + for i := 0; i < v.Len(); i++ { + val := r.getInterface(v.Index(i)) + var err error + if ctx == nil { + err = Validate(val, r.rules...) + } else { + err = ValidateWithContext(ctx, val, r.rules...) + } + if err != nil { + errs[strconv.Itoa(i)] = err + } + } + default: + return errors.New("must be an iterable (map, slice or array)") + } + + if len(errs) > 0 { + return errs + } + return nil +} + +func (r EachRule) getInterface(value reflect.Value) interface{} { + switch value.Kind() { + case reflect.Ptr, reflect.Interface: + if value.IsNil() { + return nil + } + return value.Elem().Interface() + default: + return value.Interface() + } +} + +func (r EachRule) getString(value reflect.Value) string { + switch value.Kind() { + case reflect.Ptr, reflect.Interface: + if value.IsNil() { + return "" + } + return value.Elem().String() + default: + return value.String() + } +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/error.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/error.go new file mode 100644 index 00000000..e75b1de8 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/error.go @@ -0,0 +1,180 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "bytes" + "encoding/json" + "fmt" + "sort" + "strings" + "text/template" +) + +type ( + // Error interface represents an validation error + Error interface { + Error() string + Code() string + Message() string + SetMessage(string) Error + Params() map[string]interface{} + SetParams(map[string]interface{}) Error + } + + // ErrorObject is the default validation error + // that implements the Error interface. + ErrorObject struct { + code string + message string + params map[string]interface{} + } + + // Errors represents the validation errors that are indexed by struct field names, map or slice keys. + // values are Error or Errors (for map, slice and array error value is Errors). + Errors map[string]error + + // InternalError represents an error that should NOT be treated as a validation error. + InternalError interface { + error + InternalError() error + } + + internalError struct { + error + } +) + +// NewInternalError wraps a given error into an InternalError. +func NewInternalError(err error) InternalError { + return internalError{error: err} +} + +// InternalError returns the actual error that it wraps around. +func (e internalError) InternalError() error { + return e.error +} + +// SetCode set the error's translation code. +func (e ErrorObject) SetCode(code string) Error { + e.code = code + return e +} + +// Code get the error's translation code. +func (e ErrorObject) Code() string { + return e.code +} + +// SetParams set the error's params. +func (e ErrorObject) SetParams(params map[string]interface{}) Error { + e.params = params + return e +} + +// AddParam add parameter to the error's parameters. +func (e ErrorObject) AddParam(name string, value interface{}) Error { + if e.params == nil { + e.params = make(map[string]interface{}) + } + + e.params[name] = value + return e +} + +// Params returns the error's params. +func (e ErrorObject) Params() map[string]interface{} { + return e.params +} + +// SetMessage set the error's message. +func (e ErrorObject) SetMessage(message string) Error { + e.message = message + return e +} + +// Message return the error's message. +func (e ErrorObject) Message() string { + return e.message +} + +// Error returns the error message. +func (e ErrorObject) Error() string { + if len(e.params) == 0 { + return e.message + } + + res := bytes.Buffer{} + _ = template.Must(template.New("err").Parse(e.message)).Execute(&res, e.params) + + return res.String() +} + +// Error returns the error string of Errors. +func (es Errors) Error() string { + if len(es) == 0 { + return "" + } + + keys := make([]string, len(es)) + i := 0 + for key := range es { + keys[i] = key + i++ + } + sort.Strings(keys) + + var s strings.Builder + for i, key := range keys { + if i > 0 { + s.WriteString("; ") + } + if errs, ok := es[key].(Errors); ok { + _, _ = fmt.Fprintf(&s, "%v: (%v)", key, errs) + } else { + _, _ = fmt.Fprintf(&s, "%v: %v", key, es[key].Error()) + } + } + s.WriteString(".") + return s.String() +} + +// MarshalJSON converts the Errors into a valid JSON. +func (es Errors) MarshalJSON() ([]byte, error) { + errs := map[string]interface{}{} + for key, err := range es { + if ms, ok := err.(json.Marshaler); ok { + errs[key] = ms + } else { + errs[key] = err.Error() + } + } + return json.Marshal(errs) +} + +// Filter removes all nils from Errors and returns back the updated Errors as an error. +// If the length of Errors becomes 0, it will return nil. +func (es Errors) Filter() error { + for key, value := range es { + if value == nil { + delete(es, key) + } + } + if len(es) == 0 { + return nil + } + return es +} + +// NewError create new validation error. +func NewError(code, message string) Error { + return ErrorObject{ + code: code, + message: message, + } +} + +// Assert that our ErrorObject implements the Error interface. +var _ Error = ErrorObject{} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/in.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/in.go new file mode 100644 index 00000000..97e17ffd --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/in.go @@ -0,0 +1,57 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "reflect" +) + +// ErrInInvalid is the error that returns in case of an invalid value for "in" rule. +var ErrInInvalid = NewError("validation_in_invalid", "must be a valid value") + +// In returns a validation rule that checks if a value can be found in the given list of values. +// reflect.DeepEqual() will be used to determine if two values are equal. +// For more details please refer to https://golang.org/pkg/reflect/#DeepEqual +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func In(values ...interface{}) InRule { + return InRule{ + elements: values, + err: ErrInInvalid, + } +} + +// InRule is a validation rule that validates if a value can be found in the given list of values. +type InRule struct { + elements []interface{} + err Error +} + +// Validate checks if the given value is valid or not. +func (r InRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + for _, e := range r.elements { + if reflect.DeepEqual(e, value) { + return nil + } + } + + return r.err +} + +// Error sets the error message for the rule. +func (r InRule) Error(message string) InRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r InRule) ErrorObject(err Error) InRule { + r.err = err + return r +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/length.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/length.go new file mode 100644 index 00000000..b26e1fa2 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/length.go @@ -0,0 +1,104 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "unicode/utf8" +) + +var ( + // ErrLengthTooLong is the error that returns in case of too long length. + ErrLengthTooLong = NewError("validation_length_too_long", "the length must be no more than {{.max}}") + // ErrLengthTooShort is the error that returns in case of too short length. + ErrLengthTooShort = NewError("validation_length_too_short", "the length must be no less than {{.min}}") + // ErrLengthInvalid is the error that returns in case of an invalid length. + ErrLengthInvalid = NewError("validation_length_invalid", "the length must be exactly {{.min}}") + // ErrLengthOutOfRange is the error that returns in case of out of range length. + ErrLengthOutOfRange = NewError("validation_length_out_of_range", "the length must be between {{.min}} and {{.max}}") + // ErrLengthEmptyRequired is the error that returns in case of non-empty value. + ErrLengthEmptyRequired = NewError("validation_length_empty_required", "the value must be empty") +) + +// Length returns a validation rule that checks if a value's length is within the specified range. +// If max is 0, it means there is no upper bound for the length. +// This rule should only be used for validating strings, slices, maps, and arrays. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func Length(min, max int) LengthRule { + return LengthRule{min: min, max: max, err: buildLengthRuleError(min, max)} +} + +// RuneLength returns a validation rule that checks if a string's rune length is within the specified range. +// If max is 0, it means there is no upper bound for the length. +// This rule should only be used for validating strings, slices, maps, and arrays. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +// If the value being validated is not a string, the rule works the same as Length. +func RuneLength(min, max int) LengthRule { + r := Length(min, max) + r.rune = true + + return r +} + +// LengthRule is a validation rule that checks if a value's length is within the specified range. +type LengthRule struct { + err Error + + min, max int + rune bool +} + +// Validate checks if the given value is valid or not. +func (r LengthRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + var ( + l int + err error + ) + if s, ok := value.(string); ok && r.rune { + l = utf8.RuneCountInString(s) + } else if l, err = LengthOfValue(value); err != nil { + return err + } + + if r.min > 0 && l < r.min || r.max > 0 && l > r.max || r.min == 0 && r.max == 0 && l > 0 { + return r.err + } + + return nil +} + +// Error sets the error message for the rule. +func (r LengthRule) Error(message string) LengthRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r LengthRule) ErrorObject(err Error) LengthRule { + r.err = err + return r +} + +func buildLengthRuleError(min, max int) (err Error) { + if min == 0 && max > 0 { + err = ErrLengthTooLong + } else if min > 0 && max == 0 { + err = ErrLengthTooShort + } else if min > 0 && max > 0 { + if min == max { + err = ErrLengthInvalid + } else { + err = ErrLengthOutOfRange + } + } else { + err = ErrLengthEmptyRequired + } + + return err.SetParams(map[string]interface{}{"min": min, "max": max}) +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/map.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/map.go new file mode 100644 index 00000000..106b6d80 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/map.go @@ -0,0 +1,144 @@ +package validation + +import ( + "context" + "errors" + "fmt" + "reflect" +) + +var ( + // ErrNotMap is the error that the value being validated is not a map. + ErrNotMap = errors.New("only a map can be validated") + + // ErrKeyWrongType is the error returned in case of an incorrect key type. + ErrKeyWrongType = NewError("validation_key_wrong_type", "key not the correct type") + + // ErrKeyMissing is the error returned in case of a missing key. + ErrKeyMissing = NewError("validation_key_missing", "required key is missing") + + // ErrKeyUnexpected is the error returned in case of an unexpected key. + ErrKeyUnexpected = NewError("validation_key_unexpected", "key not expected") +) + +type ( + // MapRule represents a rule set associated with a map. + MapRule struct { + keys []*KeyRules + allowExtraKeys bool + } + + // KeyRules represents a rule set associated with a map key. + KeyRules struct { + key interface{} + optional bool + rules []Rule + } +) + +// Map returns a validation rule that checks the keys and values of a map. +// This rule should only be used for validating maps, or a validation error will be reported. +// Use Key() to specify map keys that need to be validated. Each Key() call specifies a single key which can +// be associated with multiple rules. +// For example, +// validation.Map( +// validation.Key("Name", validation.Required), +// validation.Key("Value", validation.Required, validation.Length(5, 10)), +// ) +// +// A nil value is considered valid. Use the Required rule to make sure a map value is present. +func Map(keys ...*KeyRules) MapRule { + return MapRule{keys: keys} +} + +// AllowExtraKeys configures the rule to ignore extra keys. +func (r MapRule) AllowExtraKeys() MapRule { + r.allowExtraKeys = true + return r +} + +// Validate checks if the given value is valid or not. +func (r MapRule) Validate(m interface{}) error { + return r.ValidateWithContext(nil, m) +} + +// ValidateWithContext checks if the given value is valid or not. +func (r MapRule) ValidateWithContext(ctx context.Context, m interface{}) error { + value := reflect.ValueOf(m) + if value.Kind() == reflect.Ptr { + value = value.Elem() + } + if value.Kind() != reflect.Map { + // must be a map + return NewInternalError(ErrNotMap) + } + if value.IsNil() { + // treat a nil map as valid + return nil + } + + errs := Errors{} + kt := value.Type().Key() + + var extraKeys map[interface{}]bool + if !r.allowExtraKeys { + extraKeys = make(map[interface{}]bool, value.Len()) + for _, k := range value.MapKeys() { + extraKeys[k.Interface()] = true + } + } + + for _, kr := range r.keys { + var err error + if kv := reflect.ValueOf(kr.key); !kt.AssignableTo(kv.Type()) { + err = ErrKeyWrongType + } else if vv := value.MapIndex(kv); !vv.IsValid() { + if !kr.optional { + err = ErrKeyMissing + } + } else if ctx == nil { + err = Validate(vv.Interface(), kr.rules...) + } else { + err = ValidateWithContext(ctx, vv.Interface(), kr.rules...) + } + if err != nil { + if ie, ok := err.(InternalError); ok && ie.InternalError() != nil { + return err + } + errs[getErrorKeyName(kr.key)] = err + } + if !r.allowExtraKeys { + delete(extraKeys, kr.key) + } + } + + if !r.allowExtraKeys { + for key := range extraKeys { + errs[getErrorKeyName(key)] = ErrKeyUnexpected + } + } + + if len(errs) > 0 { + return errs + } + return nil +} + +// Key specifies a map key and the corresponding validation rules. +func Key(key interface{}, rules ...Rule) *KeyRules { + return &KeyRules{ + key: key, + rules: rules, + } +} + +// Optional configures the rule to ignore the key if missing. +func (r *KeyRules) Optional() *KeyRules { + r.optional = true + return r +} + +// getErrorKeyName returns the name that should be used to represent the validation error of a map key. +func getErrorKeyName(key interface{}) string { + return fmt.Sprintf("%v", key) +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/match.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/match.go new file mode 100644 index 00000000..e399bcc0 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/match.go @@ -0,0 +1,56 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "regexp" +) + +// ErrMatchInvalid is the error that returns in case of invalid format. +var ErrMatchInvalid = NewError("validation_match_invalid", "must be in a valid format") + +// Match returns a validation rule that checks if a value matches the specified regular expression. +// This rule should only be used for validating strings and byte slices, or a validation error will be reported. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func Match(re *regexp.Regexp) MatchRule { + return MatchRule{ + re: re, + err: ErrMatchInvalid, + } +} + +// MatchRule is a validation rule that checks if a value matches the specified regular expression. +type MatchRule struct { + re *regexp.Regexp + err Error +} + +// Validate checks if the given value is valid or not. +func (r MatchRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil { + return nil + } + + isString, str, isBytes, bs := StringOrBytes(value) + if isString && (str == "" || r.re.MatchString(str)) { + return nil + } else if isBytes && (len(bs) == 0 || r.re.Match(bs)) { + return nil + } + return r.err +} + +// Error sets the error message for the rule. +func (r MatchRule) Error(message string) MatchRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r MatchRule) ErrorObject(err Error) MatchRule { + r.err = err + return r +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/minmax.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/minmax.go new file mode 100644 index 00000000..f2a119f9 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/minmax.go @@ -0,0 +1,195 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "fmt" + "reflect" + "time" +) + +var ( + // ErrMinGreaterEqualThanRequired is the error that returns when a value is less than a specified threshold. + ErrMinGreaterEqualThanRequired = NewError("validation_min_greater_equal_than_required", "must be no less than {{.threshold}}") + // ErrMaxLessEqualThanRequired is the error that returns when a value is greater than a specified threshold. + ErrMaxLessEqualThanRequired = NewError("validation_max_less_equal_than_required", "must be no greater than {{.threshold}}") + // ErrMinGreaterThanRequired is the error that returns when a value is less than or equal to a specified threshold. + ErrMinGreaterThanRequired = NewError("validation_min_greater_than_required", "must be greater than {{.threshold}}") + // ErrMaxLessThanRequired is the error that returns when a value is greater than or equal to a specified threshold. + ErrMaxLessThanRequired = NewError("validation_max_less_than_required", "must be less than {{.threshold}}") +) + +// ThresholdRule is a validation rule that checks if a value satisfies the specified threshold requirement. +type ThresholdRule struct { + threshold interface{} + operator int + err Error +} + +const ( + greaterThan = iota + greaterEqualThan + lessThan + lessEqualThan +) + +// Min returns a validation rule that checks if a value is greater or equal than the specified value. +// By calling Exclusive, the rule will check if the value is strictly greater than the specified value. +// Note that the value being checked and the threshold value must be of the same type. +// Only int, uint, float and time.Time types are supported. +// An empty value is considered valid. Please use the Required rule to make sure a value is not empty. +func Min(min interface{}) ThresholdRule { + return ThresholdRule{ + threshold: min, + operator: greaterEqualThan, + err: ErrMinGreaterEqualThanRequired, + } + +} + +// Max returns a validation rule that checks if a value is less or equal than the specified value. +// By calling Exclusive, the rule will check if the value is strictly less than the specified value. +// Note that the value being checked and the threshold value must be of the same type. +// Only int, uint, float and time.Time types are supported. +// An empty value is considered valid. Please use the Required rule to make sure a value is not empty. +func Max(max interface{}) ThresholdRule { + return ThresholdRule{ + threshold: max, + operator: lessEqualThan, + err: ErrMaxLessEqualThanRequired, + } +} + +// Exclusive sets the comparison to exclude the boundary value. +func (r ThresholdRule) Exclusive() ThresholdRule { + if r.operator == greaterEqualThan { + r.operator = greaterThan + r.err = ErrMinGreaterThanRequired + } else if r.operator == lessEqualThan { + r.operator = lessThan + r.err = ErrMaxLessThanRequired + } + return r +} + +// Validate checks if the given value is valid or not. +func (r ThresholdRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + rv := reflect.ValueOf(r.threshold) + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v, err := ToInt(value) + if err != nil { + return err + } + if r.compareInt(rv.Int(), v) { + return nil + } + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + v, err := ToUint(value) + if err != nil { + return err + } + if r.compareUint(rv.Uint(), v) { + return nil + } + + case reflect.Float32, reflect.Float64: + v, err := ToFloat(value) + if err != nil { + return err + } + if r.compareFloat(rv.Float(), v) { + return nil + } + + case reflect.Struct: + t, ok := r.threshold.(time.Time) + if !ok { + return fmt.Errorf("type not supported: %v", rv.Type()) + } + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("cannot convert %v to time.Time", reflect.TypeOf(value)) + } + if v.IsZero() || r.compareTime(t, v) { + return nil + } + + default: + return fmt.Errorf("type not supported: %v", rv.Type()) + } + + return r.err.SetParams(map[string]interface{}{"threshold": r.threshold}) +} + +// Error sets the error message for the rule. +func (r ThresholdRule) Error(message string) ThresholdRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r ThresholdRule) ErrorObject(err Error) ThresholdRule { + r.err = err + return r +} + +func (r ThresholdRule) compareInt(threshold, value int64) bool { + switch r.operator { + case greaterThan: + return value > threshold + case greaterEqualThan: + return value >= threshold + case lessThan: + return value < threshold + default: + return value <= threshold + } +} + +func (r ThresholdRule) compareUint(threshold, value uint64) bool { + switch r.operator { + case greaterThan: + return value > threshold + case greaterEqualThan: + return value >= threshold + case lessThan: + return value < threshold + default: + return value <= threshold + } +} + +func (r ThresholdRule) compareFloat(threshold, value float64) bool { + switch r.operator { + case greaterThan: + return value > threshold + case greaterEqualThan: + return value >= threshold + case lessThan: + return value < threshold + default: + return value <= threshold + } +} + +func (r ThresholdRule) compareTime(threshold, value time.Time) bool { + switch r.operator { + case greaterThan: + return value.After(threshold) + case greaterEqualThan: + return value.After(threshold) || value.Equal(threshold) + case lessThan: + return value.Before(threshold) + default: + return value.Before(threshold) || value.Equal(threshold) + } +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/multipleof.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/multipleof.go new file mode 100644 index 00000000..864b8b75 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/multipleof.go @@ -0,0 +1,65 @@ +package validation + +import ( + "fmt" + "reflect" +) + +// ErrMultipleOfInvalid is the error that returns when a value is not multiple of a base. +var ErrMultipleOfInvalid = NewError("validation_multiple_of_invalid", "must be multiple of {{.base}}") + +// MultipleOf returns a validation rule that checks if a value is a multiple of the "base" value. +// Note that "base" should be of integer type. +func MultipleOf(base interface{}) MultipleOfRule { + return MultipleOfRule{ + base: base, + err: ErrMultipleOfInvalid, + } +} + +// MultipleOfRule is a validation rule that checks if a value is a multiple of the "base" value. +type MultipleOfRule struct { + base interface{} + err Error +} + +// Error sets the error message for the rule. +func (r MultipleOfRule) Error(message string) MultipleOfRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r MultipleOfRule) ErrorObject(err Error) MultipleOfRule { + r.err = err + return r +} + +// Validate checks if the value is a multiple of the "base" value. +func (r MultipleOfRule) Validate(value interface{}) error { + rv := reflect.ValueOf(r.base) + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v, err := ToInt(value) + if err != nil { + return err + } + if v%rv.Int() == 0 { + return nil + } + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + v, err := ToUint(value) + if err != nil { + return err + } + + if v%rv.Uint() == 0 { + return nil + } + default: + return fmt.Errorf("type not supported: %v", rv.Type()) + } + + return r.err.SetParams(map[string]interface{}{"base": r.base}) +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/not_in.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/not_in.go new file mode 100644 index 00000000..6e35d754 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/not_in.go @@ -0,0 +1,51 @@ +// Copyright 2018 Qiang Xue, Google LLC. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +// ErrNotInInvalid is the error that returns when a value is in a list. +var ErrNotInInvalid = NewError("validation_not_in_invalid", "must not be in list") + +// NotIn returns a validation rule that checks if a value is absent from the given list of values. +// Note that the value being checked and the possible range of values must be of the same type. +// An empty value is considered valid. Use the Required rule to make sure a value is not empty. +func NotIn(values ...interface{}) NotInRule { + return NotInRule{ + elements: values, + err: ErrNotInInvalid, + } +} + +// NotInRule is a validation rule that checks if a value is absent from the given list of values. +type NotInRule struct { + elements []interface{} + err Error +} + +// Validate checks if the given value is valid or not. +func (r NotInRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + for _, e := range r.elements { + if e == value { + return r.err + } + } + return nil +} + +// Error sets the error message for the rule. +func (r NotInRule) Error(message string) NotInRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r NotInRule) ErrorObject(err Error) NotInRule { + r.err = err + return r +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/not_nil.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/not_nil.go new file mode 100644 index 00000000..aaeb067e --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/not_nil.go @@ -0,0 +1,44 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +// ErrNotNilRequired is the error that returns when a value is Nil. +var ErrNotNilRequired = NewError("validation_not_nil_required", "is required") + +// NotNil is a validation rule that checks if a value is not nil. +// NotNil only handles types including interface, pointer, slice, and map. +// All other types are considered valid. +var NotNil = notNilRule{} + +type notNilRule struct { + err Error +} + +// Validate checks if the given value is valid or not. +func (r notNilRule) Validate(value interface{}) error { + _, isNil := Indirect(value) + if isNil { + if r.err != nil { + return r.err + } + return ErrNotNilRequired + } + return nil +} + +// Error sets the error message for the rule. +func (r notNilRule) Error(message string) notNilRule { + if r.err == nil { + r.err = ErrNotNilRequired + } + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r notNilRule) ErrorObject(err Error) notNilRule { + r.err = err + return r +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/required.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/required.go new file mode 100644 index 00000000..61b888bf --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/required.go @@ -0,0 +1,74 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +var ( + // ErrRequired is the error that returns when a value is required. + ErrRequired = NewError("validation_required", "cannot be blank") + // ErrNilOrNotEmpty is the error that returns when a value is not nil and is empty. + ErrNilOrNotEmpty = NewError("validation_nil_or_not_empty_required", "cannot be blank") +) + +// Required is a validation rule that checks if a value is not empty. +// A value is considered not empty if +// - integer, float: not zero +// - bool: true +// - string, array, slice, map: len() > 0 +// - interface, pointer: not nil and the referenced value is not empty +// - any other types +var Required = RequiredRule{skipNil: false, condition: true} + +// NilOrNotEmpty checks if a value is a nil pointer or a value that is not empty. +// NilOrNotEmpty differs from Required in that it treats a nil pointer as valid. +var NilOrNotEmpty = RequiredRule{skipNil: true, condition: true} + +// RequiredRule is a rule that checks if a value is not empty. +type RequiredRule struct { + condition bool + skipNil bool + err Error +} + +// Validate checks if the given value is valid or not. +func (r RequiredRule) Validate(value interface{}) error { + if r.condition { + value, isNil := Indirect(value) + if r.skipNil && !isNil && IsEmpty(value) || !r.skipNil && (isNil || IsEmpty(value)) { + if r.err != nil { + return r.err + } + if r.skipNil { + return ErrNilOrNotEmpty + } + return ErrRequired + } + } + return nil +} + +// When sets the condition that determines if the validation should be performed. +func (r RequiredRule) When(condition bool) RequiredRule { + r.condition = condition + return r +} + +// Error sets the error message for the rule. +func (r RequiredRule) Error(message string) RequiredRule { + if r.err == nil { + if r.skipNil { + r.err = ErrNilOrNotEmpty + } else { + r.err = ErrRequired + } + } + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r RequiredRule) ErrorObject(err Error) RequiredRule { + r.err = err + return r +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/string.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/string.go new file mode 100644 index 00000000..d6d45d89 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/string.go @@ -0,0 +1,64 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +type stringValidator func(string) bool + +// StringRule is a rule that checks a string variable using a specified stringValidator. +type StringRule struct { + validate stringValidator + err Error +} + +// NewStringRule creates a new validation rule using a function that takes a string value and returns a bool. +// The rule returned will use the function to check if a given string or byte slice is valid or not. +// An empty value is considered to be valid. Please use the Required rule to make sure a value is not empty. +func NewStringRule(validator stringValidator, message string) StringRule { + return StringRule{ + validate: validator, + err: NewError("", message), + } +} + +// NewStringRuleWithError creates a new validation rule using a function that takes a string value and returns a bool. +// The rule returned will use the function to check if a given string or byte slice is valid or not. +// An empty value is considered to be valid. Please use the Required rule to make sure a value is not empty. +func NewStringRuleWithError(validator stringValidator, err Error) StringRule { + return StringRule{ + validate: validator, + err: err, + } +} + +// Error sets the error message for the rule. +func (r StringRule) Error(message string) StringRule { + r.err = r.err.SetMessage(message) + return r +} + +// ErrorObject sets the error struct for the rule. +func (r StringRule) ErrorObject(err Error) StringRule { + r.err = err + return r +} + +// Validate checks if the given value is valid or not. +func (r StringRule) Validate(value interface{}) error { + value, isNil := Indirect(value) + if isNil || IsEmpty(value) { + return nil + } + + str, err := EnsureString(value) + if err != nil { + return err + } + + if r.validate(str) { + return nil + } + + return r.err +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/struct.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/struct.go new file mode 100644 index 00000000..d63619da --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/struct.go @@ -0,0 +1,169 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "context" + "errors" + "fmt" + "reflect" + "strings" +) + +var ( + // ErrStructPointer is the error that a struct being validated is not specified as a pointer. + ErrStructPointer = errors.New("only a pointer to a struct can be validated") +) + +type ( + // ErrFieldPointer is the error that a field is not specified as a pointer. + ErrFieldPointer int + + // ErrFieldNotFound is the error that a field cannot be found in the struct. + ErrFieldNotFound int + + // FieldRules represents a rule set associated with a struct field. + FieldRules struct { + fieldPtr interface{} + rules []Rule + } +) + +// Error returns the error string of ErrFieldPointer. +func (e ErrFieldPointer) Error() string { + return fmt.Sprintf("field #%v must be specified as a pointer", int(e)) +} + +// Error returns the error string of ErrFieldNotFound. +func (e ErrFieldNotFound) Error() string { + return fmt.Sprintf("field #%v cannot be found in the struct", int(e)) +} + +// ValidateStruct validates a struct by checking the specified struct fields against the corresponding validation rules. +// Note that the struct being validated must be specified as a pointer to it. If the pointer is nil, it is considered valid. +// Use Field() to specify struct fields that need to be validated. Each Field() call specifies a single field which +// should be specified as a pointer to the field. A field can be associated with multiple rules. +// For example, +// +// value := struct { +// Name string +// Value string +// }{"name", "demo"} +// err := validation.ValidateStruct(&value, +// validation.Field(&a.Name, validation.Required), +// validation.Field(&a.Value, validation.Required, validation.Length(5, 10)), +// ) +// fmt.Println(err) +// // Value: the length must be between 5 and 10. +// +// An error will be returned if validation fails. +func ValidateStruct(structPtr interface{}, fields ...*FieldRules) error { + return ValidateStructWithContext(nil, structPtr, fields...) +} + +// ValidateStructWithContext validates a struct with the given context. +// The only difference between ValidateStructWithContext and ValidateStruct is that the former will +// validate struct fields with the provided context. +// Please refer to ValidateStruct for the detailed instructions on how to use this function. +func ValidateStructWithContext(ctx context.Context, structPtr interface{}, fields ...*FieldRules) error { + value := reflect.ValueOf(structPtr) + if value.Kind() != reflect.Ptr || !value.IsNil() && value.Elem().Kind() != reflect.Struct { + // must be a pointer to a struct + return NewInternalError(ErrStructPointer) + } + if value.IsNil() { + // treat a nil struct pointer as valid + return nil + } + value = value.Elem() + + errs := Errors{} + + for i, fr := range fields { + fv := reflect.ValueOf(fr.fieldPtr) + if fv.Kind() != reflect.Ptr { + return NewInternalError(ErrFieldPointer(i)) + } + ft := findStructField(value, fv) + if ft == nil { + return NewInternalError(ErrFieldNotFound(i)) + } + var err error + if ctx == nil { + err = Validate(fv.Elem().Interface(), fr.rules...) + } else { + err = ValidateWithContext(ctx, fv.Elem().Interface(), fr.rules...) + } + if err != nil { + if ie, ok := err.(InternalError); ok && ie.InternalError() != nil { + return err + } + if ft.Anonymous { + // merge errors from anonymous struct field + if es, ok := err.(Errors); ok { + for name, value := range es { + errs[name] = value + } + continue + } + } + errs[getErrorFieldName(ft)] = err + } + } + + if len(errs) > 0 { + return errs + } + return nil +} + +// Field specifies a struct field and the corresponding validation rules. +// The struct field must be specified as a pointer to it. +func Field(fieldPtr interface{}, rules ...Rule) *FieldRules { + return &FieldRules{ + fieldPtr: fieldPtr, + rules: rules, + } +} + +// findStructField looks for a field in the given struct. +// The field being looked for should be a pointer to the actual struct field. +// If found, the field info will be returned. Otherwise, nil will be returned. +func findStructField(structValue reflect.Value, fieldValue reflect.Value) *reflect.StructField { + ptr := fieldValue.Pointer() + for i := structValue.NumField() - 1; i >= 0; i-- { + sf := structValue.Type().Field(i) + if ptr == structValue.Field(i).UnsafeAddr() { + // do additional type comparison because it's possible that the address of + // an embedded struct is the same as the first field of the embedded struct + if sf.Type == fieldValue.Elem().Type() { + return &sf + } + } + if sf.Anonymous { + // delve into anonymous struct to look for the field + fi := structValue.Field(i) + if sf.Type.Kind() == reflect.Ptr { + fi = fi.Elem() + } + if fi.Kind() == reflect.Struct { + if f := findStructField(fi, fieldValue); f != nil { + return f + } + } + } + } + return nil +} + +// getErrorFieldName returns the name that should be used to represent the validation error of a struct field. +func getErrorFieldName(f *reflect.StructField) string { + if tag := f.Tag.Get(ErrorTag); tag != "" && tag != "-" { + if cps := strings.SplitN(tag, ",", 2); cps[0] != "" { + return cps[0] + } + } + return f.Name +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/util.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/util.go new file mode 100644 index 00000000..b15fd9a2 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/util.go @@ -0,0 +1,163 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package validation + +import ( + "database/sql/driver" + "errors" + "fmt" + "reflect" + "time" +) + +var ( + bytesType = reflect.TypeOf([]byte(nil)) + valuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() +) + +// EnsureString ensures the given value is a string. +// If the value is a byte slice, it will be typecast into a string. +// An error is returned otherwise. +func EnsureString(value interface{}) (string, error) { + v := reflect.ValueOf(value) + if v.Kind() == reflect.String { + return v.String(), nil + } + if v.Type() == bytesType { + return string(v.Interface().([]byte)), nil + } + return "", errors.New("must be either a string or byte slice") +} + +// StringOrBytes typecasts a value into a string or byte slice. +// Boolean flags are returned to indicate if the typecasting succeeds or not. +func StringOrBytes(value interface{}) (isString bool, str string, isBytes bool, bs []byte) { + v := reflect.ValueOf(value) + if v.Kind() == reflect.String { + str = v.String() + isString = true + } else if v.Kind() == reflect.Slice && v.Type() == bytesType { + bs = v.Interface().([]byte) + isBytes = true + } + return +} + +// LengthOfValue returns the length of a value that is a string, slice, map, or array. +// An error is returned for all other types. +func LengthOfValue(value interface{}) (int, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.String, reflect.Slice, reflect.Map, reflect.Array: + return v.Len(), nil + } + return 0, fmt.Errorf("cannot get the length of %v", v.Kind()) +} + +// ToInt converts the given value to an int64. +// An error is returned for all incompatible types. +func ToInt(value interface{}) (int64, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int(), nil + } + return 0, fmt.Errorf("cannot convert %v to int64", v.Kind()) +} + +// ToUint converts the given value to an uint64. +// An error is returned for all incompatible types. +func ToUint(value interface{}) (uint64, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint(), nil + } + return 0, fmt.Errorf("cannot convert %v to uint64", v.Kind()) +} + +// ToFloat converts the given value to a float64. +// An error is returned for all incompatible types. +func ToFloat(value interface{}) (float64, error) { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Float32, reflect.Float64: + return v.Float(), nil + } + return 0, fmt.Errorf("cannot convert %v to float64", v.Kind()) +} + +// IsEmpty checks if a value is empty or not. +// A value is considered empty if +// - integer, float: zero +// - bool: false +// - string, array: len() == 0 +// - slice, map: nil or len() == 0 +// - interface, pointer: nil or the referenced value is empty +func IsEmpty(value interface{}) bool { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.String, reflect.Array, reflect.Map, reflect.Slice: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Invalid: + return true + case reflect.Interface, reflect.Ptr: + if v.IsNil() { + return true + } + return IsEmpty(v.Elem().Interface()) + case reflect.Struct: + v, ok := value.(time.Time) + if ok && v.IsZero() { + return true + } + } + + return false +} + +// Indirect returns the value that the given interface or pointer references to. +// If the value implements driver.Valuer, it will deal with the value returned by +// the Value() method instead. A boolean value is also returned to indicate if +// the value is nil or not (only applicable to interface, pointer, map, and slice). +// If the value is neither an interface nor a pointer, it will be returned back. +func Indirect(value interface{}) (interface{}, bool) { + rv := reflect.ValueOf(value) + kind := rv.Kind() + switch kind { + case reflect.Invalid: + return nil, true + case reflect.Ptr, reflect.Interface: + if rv.IsNil() { + return nil, true + } + return Indirect(rv.Elem().Interface()) + case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: + if rv.IsNil() { + return nil, true + } + } + + if rv.Type().Implements(valuerType) { + return indirectValuer(value.(driver.Valuer)) + } + + return value, false +} + +func indirectValuer(valuer driver.Valuer) (interface{}, bool) { + if value, err := valuer.Value(); value != nil && err == nil { + return Indirect(value) + } + return nil, true +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/validation.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/validation.go new file mode 100644 index 00000000..ec7a1615 --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/validation.go @@ -0,0 +1,272 @@ +// Copyright 2016 Qiang Xue. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// Package validation provides configurable and extensible rules for validating data of various types. +package validation + +import ( + "context" + "fmt" + "reflect" + "strconv" +) + +type ( + // Validatable is the interface indicating the type implementing it supports data validation. + Validatable interface { + // Validate validates the data and returns an error if validation fails. + Validate() error + } + + // ValidatableWithContext is the interface indicating the type implementing it supports context-aware data validation. + ValidatableWithContext interface { + // ValidateWithContext validates the data with the given context and returns an error if validation fails. + ValidateWithContext(ctx context.Context) error + } + + // Rule represents a validation rule. + Rule interface { + // Validate validates a value and returns a value if validation fails. + Validate(value interface{}) error + } + + // RuleWithContext represents a context-aware validation rule. + RuleWithContext interface { + // ValidateWithContext validates a value and returns a value if validation fails. + ValidateWithContext(ctx context.Context, value interface{}) error + } + + // RuleFunc represents a validator function. + // You may wrap it as a Rule by calling By(). + RuleFunc func(value interface{}) error + + // RuleWithContextFunc represents a validator function that is context-aware. + // You may wrap it as a Rule by calling WithContext(). + RuleWithContextFunc func(ctx context.Context, value interface{}) error +) + +var ( + // ErrorTag is the struct tag name used to customize the error field name for a struct field. + ErrorTag = "json" + + // Skip is a special validation rule that indicates all rules following it should be skipped. + Skip = skipRule{skip: true} + + validatableType = reflect.TypeOf((*Validatable)(nil)).Elem() + validatableWithContextType = reflect.TypeOf((*ValidatableWithContext)(nil)).Elem() +) + +// Validate validates the given value and returns the validation error, if any. +// +// Validate performs validation using the following steps: +// 1. For each rule, call its `Validate()` to validate the value. Return if any error is found. +// 2. If the value being validated implements `Validatable`, call the value's `Validate()`. +// Return with the validation result. +// 3. If the value being validated is a map/slice/array, and the element type implements `Validatable`, +// for each element call the element value's `Validate()`. Return with the validation result. +func Validate(value interface{}, rules ...Rule) error { + for _, rule := range rules { + if s, ok := rule.(skipRule); ok && s.skip { + return nil + } + if err := rule.Validate(value); err != nil { + return err + } + } + + rv := reflect.ValueOf(value) + if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface) && rv.IsNil() { + return nil + } + + if v, ok := value.(Validatable); ok { + return v.Validate() + } + + switch rv.Kind() { + case reflect.Map: + if rv.Type().Elem().Implements(validatableType) { + return validateMap(rv) + } + case reflect.Slice, reflect.Array: + if rv.Type().Elem().Implements(validatableType) { + return validateSlice(rv) + } + case reflect.Ptr, reflect.Interface: + return Validate(rv.Elem().Interface()) + } + + return nil +} + +// ValidateWithContext validates the given value with the given context and returns the validation error, if any. +// +// ValidateWithContext performs validation using the following steps: +// 1. For each rule, call its `ValidateWithContext()` to validate the value if the rule implements `RuleWithContext`. +// Otherwise call `Validate()` of the rule. Return if any error is found. +// 2. If the value being validated implements `ValidatableWithContext`, call the value's `ValidateWithContext()` +// and return with the validation result. +// 3. If the value being validated implements `Validatable`, call the value's `Validate()` +// and return with the validation result. +// 4. If the value being validated is a map/slice/array, and the element type implements `ValidatableWithContext`, +// for each element call the element value's `ValidateWithContext()`. Return with the validation result. +// 5. If the value being validated is a map/slice/array, and the element type implements `Validatable`, +// for each element call the element value's `Validate()`. Return with the validation result. +func ValidateWithContext(ctx context.Context, value interface{}, rules ...Rule) error { + for _, rule := range rules { + if s, ok := rule.(skipRule); ok && s.skip { + return nil + } + if rc, ok := rule.(RuleWithContext); ok { + if err := rc.ValidateWithContext(ctx, value); err != nil { + return err + } + } else if err := rule.Validate(value); err != nil { + return err + } + } + + rv := reflect.ValueOf(value) + if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface) && rv.IsNil() { + return nil + } + + if v, ok := value.(ValidatableWithContext); ok { + return v.ValidateWithContext(ctx) + } + + if v, ok := value.(Validatable); ok { + return v.Validate() + } + + switch rv.Kind() { + case reflect.Map: + if rv.Type().Elem().Implements(validatableWithContextType) { + return validateMapWithContext(ctx, rv) + } + if rv.Type().Elem().Implements(validatableType) { + return validateMap(rv) + } + case reflect.Slice, reflect.Array: + if rv.Type().Elem().Implements(validatableWithContextType) { + return validateSliceWithContext(ctx, rv) + } + if rv.Type().Elem().Implements(validatableType) { + return validateSlice(rv) + } + case reflect.Ptr, reflect.Interface: + return ValidateWithContext(ctx, rv.Elem().Interface()) + } + + return nil +} + +// validateMap validates a map of validatable elements +func validateMap(rv reflect.Value) error { + errs := Errors{} + for _, key := range rv.MapKeys() { + if mv := rv.MapIndex(key).Interface(); mv != nil { + if err := mv.(Validatable).Validate(); err != nil { + errs[fmt.Sprintf("%v", key.Interface())] = err + } + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +// validateMapWithContext validates a map of validatable elements with the given context. +func validateMapWithContext(ctx context.Context, rv reflect.Value) error { + errs := Errors{} + for _, key := range rv.MapKeys() { + if mv := rv.MapIndex(key).Interface(); mv != nil { + if err := mv.(ValidatableWithContext).ValidateWithContext(ctx); err != nil { + errs[fmt.Sprintf("%v", key.Interface())] = err + } + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +// validateSlice validates a slice/array of validatable elements +func validateSlice(rv reflect.Value) error { + errs := Errors{} + l := rv.Len() + for i := 0; i < l; i++ { + if ev := rv.Index(i).Interface(); ev != nil { + if err := ev.(Validatable).Validate(); err != nil { + errs[strconv.Itoa(i)] = err + } + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +// validateSliceWithContext validates a slice/array of validatable elements with the given context. +func validateSliceWithContext(ctx context.Context, rv reflect.Value) error { + errs := Errors{} + l := rv.Len() + for i := 0; i < l; i++ { + if ev := rv.Index(i).Interface(); ev != nil { + if err := ev.(ValidatableWithContext).ValidateWithContext(ctx); err != nil { + errs[strconv.Itoa(i)] = err + } + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +type skipRule struct { + skip bool +} + +func (r skipRule) Validate(interface{}) error { + return nil +} + +// When determines if all rules following it should be skipped. +func (r skipRule) When(condition bool) skipRule { + r.skip = condition + return r +} + +type inlineRule struct { + f RuleFunc + fc RuleWithContextFunc +} + +func (r *inlineRule) Validate(value interface{}) error { + if r.f == nil { + return r.fc(context.Background(), value) + } + return r.f(value) +} + +func (r *inlineRule) ValidateWithContext(ctx context.Context, value interface{}) error { + if r.fc == nil { + return r.f(value) + } + return r.fc(ctx, value) +} + +// By wraps a RuleFunc into a Rule. +func By(f RuleFunc) Rule { + return &inlineRule{f: f} +} + +// WithContext wraps a RuleWithContextFunc into a context-aware Rule. +func WithContext(f RuleWithContextFunc) Rule { + return &inlineRule{fc: f} +} diff --git a/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/when.go b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/when.go new file mode 100644 index 00000000..7bcdff5a --- /dev/null +++ b/gateway/vendor/github.com/go-ozzo/ozzo-validation/v4/when.go @@ -0,0 +1,47 @@ +package validation + +import "context" + +// When returns a validation rule that executes the given list of rules when the condition is true. +func When(condition bool, rules ...Rule) WhenRule { + return WhenRule{ + condition: condition, + rules: rules, + elseRules: []Rule{}, + } +} + +// WhenRule is a validation rule that executes the given list of rules when the condition is true. +type WhenRule struct { + condition bool + rules []Rule + elseRules []Rule +} + +// Validate checks if the condition is true and if so, it validates the value using the specified rules. +func (r WhenRule) Validate(value interface{}) error { + return r.ValidateWithContext(nil, value) +} + +// ValidateWithContext checks if the condition is true and if so, it validates the value using the specified rules. +func (r WhenRule) ValidateWithContext(ctx context.Context, value interface{}) error { + if r.condition { + if ctx == nil { + return Validate(value, r.rules...) + } else { + return ValidateWithContext(ctx, value, r.rules...) + } + } + + if ctx == nil { + return Validate(value, r.elseRules...) + } else { + return ValidateWithContext(ctx, value, r.elseRules...) + } +} + +// Else returns a validation rule that executes the given list of rules when the condition is false. +func (r WhenRule) Else(rules ...Rule) WhenRule { + r.elseRules = rules + return r +} diff --git a/gateway/vendor/modules.txt b/gateway/vendor/modules.txt index 797937ed..0b952a11 100644 --- a/gateway/vendor/modules.txt +++ b/gateway/vendor/modules.txt @@ -7,6 +7,9 @@ github.com/cespare/xxhash/v2 # github.com/docker/distribution v2.8.1+incompatible ## explicit github.com/docker/distribution/uuid +# github.com/go-ozzo/ozzo-validation/v4 v4.3.0 +## explicit; go 1.13 +github.com/go-ozzo/ozzo-validation/v4 # github.com/gogo/protobuf v1.3.2 ## explicit; go 1.15 github.com/gogo/protobuf/gogoproto diff --git a/go.mod b/go.mod index 945ea1ad..9cca1ed0 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/openfaas/faas -go 1.17 \ No newline at end of file +go 1.17