Pywalify - evaluate nested maps - validation

I'm using pykwalify to validate a schema.
Given this yaml:
variables:
dev:
options:
key: value
uat:
key: value
key2: value
prd:
key: value
key2: value
Under variables, any map should be allowed.
Under that second level (dev, uat, prd) - any key should be allowed, EXCEPT options. "options" should not be allowed here.
I've tried using a regex, but this is only evaluating the top level, and I'm not quite sure how evaluate the level nested under that "dev, uat, prd" level.
variables:
type: map
matching-rule: all
mapping:
regex;([^,]+):
type: any
regex;(^(?!.*options:).*$):
type: any
Another potential option would be if I have to explicitly list the values that are allowed, that would work too.

I see two issues in your snippet:
The regex to match anything but "options" is wrong.
The schema isn't properly structured for the nested mapping.
The following schema should provide what you need:
variables:
type: map
matching-rule: all
mapping:
regex;([^,]+):
type: map
mapping:
regex;(^(?!options$).*):
type: any

Related

Open API Spec V2.0 - Default value of a field of type Enum

I have a request body for an API specification in Swagger V2.0, which looks like follows.
"/uri/path":
...
parameters:
- in: body
...
schema:
$ref: '#/definitions/StatusObject'
definitions:
StatusObject:
status:
$ref: '#/definitions/StatusEnum'
StatusEnum:
type: string
enum: ['ALPHA', 'BRAVO', 'UNKNOWN']
Now, I want StatusObject.status to have the value UNKNOWN by default, if it is not set from the client end. I tried to achieve this as follows, with no luck.
"/uri/path":
...
parameters:
- in: body
...
schema:
$ref: '#/definitions/StatusObject'
definitions:
StatusObject:
status:
$ref: '#/definitions/StatusEnum'
default: 'UNKNOWN'
StatusEnum:
type: string
enum: ['ALPHA', 'BRAVO', 'UNKNOWN']
I also have tried with '#/definitions/StatusEnum.UNKNOWN' which again didn't work. Combed through the documentation as well but couldn't find anything further. What am I missing?
Response to marked duplicate
What I am trying to achieve is to set a default value for this property status. This works when the enum is defined in line as follows.
"/uri/path":
...
parameters:
- in: body
...
schema:
$ref: '#/definitions/StatusObject'
definitions:
StatusObject:
status:
type: string
enum:
- 'ALPHA'
- 'BRAVO'
- 'UNKNOWN'
default: 'UNKNOWN'
But, this won't work for me, as I'd like to reuse the enum, which otherwise I'll have to repeat at multiple places.
Since this is just a workaround and I am not sure if I can confirm if this is an answer, I won't mark this as accepted answer. That way, I think it will be still open for someone who figured out the right way, or a better way to achieve the expectation.
Apparently, the problem is with $ref. It's already known that the siblings of $ref are ignored in OpenAPI V2.0. So, enforcing any further constraints once you use $ref won't be possible.
For my specific use case, since I want to reuse my enum definition, I used YAML Anchors as defined in V2.0 docs. Even though the enum definition is repeated in each POJO it's not that much of a headache to manage, at least for the time being. The implementation I came up is as follows.
"/uri/path":
...
parameters:
- in: body
...
schema:
$ref: '#/definitions/StatusObject'
definitions:
StatusObject:
status:
enum: *STATUS_ENUM # Referencing the anchor
default: 'UNKNOWN'
StatusEnum:
type: string
enum: &STATUS_ENUM # This is the anchor
- 'ALPHA'
- 'BRAVO'
- 'UNKNOWN'
It must also be noted that, the enum values in this case cannot be defined using array syntax (i.e. ['ALPHA', 'BRAVO', 'UNKNOWN']) as it'll break the YAML syntax rules when you try to use YAML anchors alongside that.

The request in invalid - unrecognized type: string when applying kubectl [duplicate]

I want to set a boolean variable in configMap (or secret):
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: mlo-stage
data:
webpack_dev_server: false
But when I apply it, I get the following error:
The request is invalid: patch: Invalid value: "map[data:map[webpack_dev_server:false] metadata:map[annotations:map[kubectl.kubernetes.io/last-applied-configuration:{ blah blah blah}]]]": unrecognized type: string
I have tried to change the value to Off/No/False, all having the same problem.
It seems that the value of the keys in the data map can only be string, I have tried to change the value to "false", the yaml file is OK, but then the variable becomes a string but not boolean.
what should I do if I want to pass a boolean as value?
Values in a ConfigMap must be key-value string values or files.
Change:
data:
webpack_dev_server: false
To:
data:
webpack_dev_server: "false"
To your question:
what should I do if I want to pass a boolean as value?
You may handle this in the application, transform from string to bool.

How do you specify possible values for an OpenAPI query parameter? [duplicate]

I am writing an OpenAPI (Swagger) definition where a query parameter can take none, or N values, like this:
/path?sort=field1,field2
How can I write this in OpenAPI YAML?
I tried the following, but it does not produce the expected result:
- name: sort
in: query
schema:
type: string
enum: [field1,field2,field3]
allowEmptyValue: true
required: false
description: Sort the results by attributes. (See http://jsonapi.org/format/1.1/#fetching-sorting)
A query parameter containing a comma-separated list of values is defined as an array. If the values are predefined, then it's an array of enum.
By default, an array may have any number of items, which matches your "none or more" requirement. If needed, you can restrict the number of items using minItems and maxItems, and optionally enforce uniqueItems: true.
OpenAPI 2.0
The parameter definition would look as follows. collectionFormat: csv indicates that the values are comma-separated, but this is the default format so it can be omitted.
parameters:
- name: sort
in: query
type: array # <-----
items:
type: string
enum: [field1, field2, field3]
collectionFormat: csv # <-----
required: false
description: Sort the results by attributes. (See http://jsonapi.org/format/1.1/#fetching-sorting)
OpenAPI 3.x
collectionFormat: csv from OpenAPI 2.0 has been replaced with style: form + explode: false. style: form is the default style for query parameters, so it can be omitted.
parameters:
- name: sort
in: query
schema:
type: array # <-----
items:
type: string
enum: [field1, field2, field3]
required: false
description: Sort the results by attributes. (See http://jsonapi.org/format/1.1/#fetching-sorting)
explode: false # <-----
I think there's no need for allowEmptyValue, because an empty array will be effectively an empty value in this scenario. Moreover, allowEmptyValue is not recommended for use since OpenAPI 3.0.2 "as it will be removed in a future version."

Pass multiple parameters to DBParameterGroup in YAML CloudFormation

I have the following cloudformation template. The goal is to only create a parameter group if the user wants to and then to populate the RDS parameters in the parameter group with the contents of the cloudformation template parameters.
Parameters:
UseCustomParameterGroup:
Description: Toggle to 'Yes' to create a new parameter group.
Type: String
AllowedValues: ['Yes', 'No']
Default: 'No'
CustomParameters:
Description: Add custom parameters to your custom parameter group. Creating a custom parameter group without parameters creates a mirror of the default group.
Type: String
Conditions:
UseCustomParameterGroup: !Equals [!Ref 'UseCustomParameterGroup', 'Yes']
Resources:
CustomParameterGroup:
Type: AWS::RDS::DBParameterGroup
Condition: 'UseCustomParameterGroup'
Properties:
Family: "postgres10"
Parameters: !Ref "CustomParameters"
If I call this template from another template as so, it will fail with the error Value of property Parameters must be an object
Parameters:
USECUSTOMPARAMETERGROUP: 'Yes'
CUSTOMPARAMETERS: '{
"shared_preload_libraries": "pg_stat_statements",
"pg_stat_statements.track": "all"
}'
Resources:
Postgres:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://..../rds-postgres-instance.yaml
TimeoutInMinutes: '60'
Parameters:
UseCustomParameterGroup: !Ref USECUSTOMPARAMETERGROUP
CustomParameters: !Ref CUSTOMPARAMETERS
The documentation for AWS::RDS::DBParameterGroup states the following for the Parameters parameter:
Type: A JSON object consisting of string key-value pairs, as shown in the following example
"Parameters" : { "Key1" : "Value1", "Key2" : "Value2", "Key3" : "Value3" }
I think this may be out of date for the YAML version of Cloudformation, but there is no documentation on how to pass this value multiple parameters.
I want the user to be able to define as few or many RDS parameters as they please without having to account for any of the thousands of possible parameters available to RDS.
Cloudformation doesn't allow you to convert string parameters to JSON objects (or YAML for that matter), your parameters are meant to be used as values for your definition keys.
Some other frameworks like serverless overcome this limitation by using a different template language that generates a Cloudformation compatible artifact after some processing, if this feature is critical to your process I advise you to migrate to one of those frameworks.

Tosca - specifying map type properties

What is the correct way of specifying constraints and the defaults for the "map" type? I.e., is there is an option of specifying "valid_values" for both: keys and values?
When we specify constraints at the "entry_schema" level, are they considered for keys, values, for both? Can we have separate lists of valid_values - one for keys and one for values? Or should we specify them both in a single list like in the following example?
properties:
<property_name>:
type: map
entry_schema:
type: string
constraints:
- valid_values:
- "key1":"val1"
- "key2":"val2"
- "key3":"val3"
- "key4":"val4"
default:
key1: "val1"
key2: "val2"

Resources