Tosca - specifying map type properties - yaml

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"

Related

How to reuse an array in a schema?

The following schema doesn't pass the validation with jsonschema
$defs:
names:
- n1
- n2
- n3
properties:
name:
enum:
$ref: "#/$defs/names"
With a minimal fragment such as name: "n1", jsonschema will complain jsonschema.exceptions.SchemaError: ['n1', 'n2', 'n3'] is not of type 'object', 'boolean'.
So can I put an array in a schema's $defs? I don't see this limitation in the tutorial on json-schema.org. If not, how can I reuse an array in a schema?
First, the enum property expects a a list of values not a schema (via the $ref keyword). Second, the schemas in $defs (in your example names) have to be a schema - directly setting a list indeed doesn't work.
To make your example work, you have to use the enum keyword as part of the $defs schema like this:
"$defs":
names:
enum:
- n1
- n2
- n2
properties:
name:
"$ref": "#/$defs/names"
This allows you to validate as expected: https://www.jsonschemavalidator.net/s/RGx6COQf

How to show all the parameters names as comma separated string and assign to One Varaible in YAML Azure Pipelines

How to show all the parameter's names as comma-separated strings (concatenated) and assign them to One Variable in YAML Azure so that i can use this variable in several places
i tried using
parameters:
- name: Var1
displayName: Testing
type: string
- name: Var2
displayName: Coding
type: string
- name: Var3
displayName: Marketing
type: string
variables:
- name: allParametersString
${{each item in parameters}}:
value: $allParametersString + ','+ item.displayName
my desired output is upon using $allParametersString I should get
Testing,Coding,Marketing
but this is leaving an error mentioning 'value' is already defined so can anyone help me? regarding this, I am searching for a solution for 2 weeks :(
I found the way of using bash to assign values will work for this i did
variables:
- name: allParametersString
value: ' '
steps:
- ${{ each parameter in parameters }}:
# the below code will help us reassign the values to variables with bash so i am appending all parameters separated by comma
- bash: echo '##vso[task.setvariable variable=allParametersString]$(allParametersString)${{ parameter.Key }}, '
- script:
echo 'printing all parameters names separated by comma .->$(allParametersString)'
Please let me know if I can improve it more
this helps me understand that in order to reassign or assign twice or concatenate the string using YAML this is the one way of doing it
Your current thinking is not feasible.
There are several things that bind you.
1, The first is the processing logic of yml expression in DevOps.
See this official document:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/runs?view=azure-devops#process-the-pipeline
From the first sentence given, we know your yml will be expanded like this:
parameters:
- name: Var1
displayName: Testing
type: string
default: value1
- name: Var2
displayName: Coding
type: string
default: value2
- name: Var3
displayName: Marketing
type: string
default: value3
variables:
- name: allParametersString
value: xxx
value: xxx
value: xxx
variable of yml concept doesn't allow the written method of the above. That's why you encountered error 'value' is already defined.
2, The second is the structure allowed by DevOps yml files.
Every section of yml definition has limited predefined key. This means that compile time cannot find other container to store the variable.
3, I am afraid the usage of yml expression does not support you to do so.
Refer to this:
Each Keyword This tell you the standard usage of 'each':
You can use the each keyword to loop through parameters with the
object type.
JOIN Expression
This is the way the DevOps yml pipeline provides compile-time flattening of data, but it doesn't work in your case.
And there's no such thing as an index or subscript to navigate to the last run.
4, By the way, the item object doesn't have such information 'displayName':
trigger:
- none
parameters:
- name: Var1
displayName: Testing
type: string
default: value1
- name: Var2
displayName: Coding
type: string
default: value2
- name: Var3
displayName: Marketing
type: string
default: value3
steps:
- ${{each item in parameters}}:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "${{ convertToJson(item) }}"
Result:
The DevOps yml pipeline has no built-in features to implement your needs. If you have to do this, a feasible method is to call the API to get the content of the yml file, then parse and get the parameter part (this is actually a self-designed parser), and then combine the acquired parameters into the variable in the script And pass logging command set variable(isoutput=true). In this way, other tasks can use this combined variable.
This can be done, but is overly complicated and you need to consider whether it is necessary to do such a thing.

Pywalify - evaluate nested maps

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

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.

Resources