Parse yaml with keys provide errors - go

I’ve the following yaml which I need to parse,
I’ve tried with the following
Build-t:
before: test1
- value : dddd
- bbb: zzzz
after: test2
- value: bbb
- aaa: aaaa
I’ve tried with the following:
type root struct{
build type Build `yaml:"Build-t,omitempty"`
}
type Build struct {
Before map[string]interface{} `yaml:"before,omitempty"`
After map[string]interface{} `yaml:"after,omitempty"`
}
Now when I parse it I got error,
What I need is to get the values from the object before and after which are hardcoded value in the yaml
And all the others value under it are dynmically can be added therefor I put it as interface
btw, if I change the root to this its working and I see all the fields under the Build-t but the before and after are like keys ...
type root struct{
build type map[string]interface{} `yaml:"Build-t,omitempty"`
}
the error is:
line 6: cannot unmarshal !!str `test1` into map[string]interface {}
line 7: cannot unmarshal !!str `test2` into map[string]interface {}
see the yaml valid here
https://codebeautify.org/yaml-validator/cb705458

That sounds correct - the YAML is invalid. Did you mean something like this?
Build-t:
before:
test1:
- value: dddd
- bbb: zzzz
after:
test2:
- value: bbb
- aaa: aaaa
Remember that the whitespace is important, and it's a key-value structure - so your values can either be strings, or substructures - not both.
Also, that yaml validator... I can't seem to make it declare anything as invalid!

Related

Pass an entire yaml from values to templates without filling empty fields with nulls

I am trying to pass given part of values.yaml into helm template:
receivers:
test1:
test2:
test3:
test4:
using function:
{{ .Values.receivers | toYaml | nindent 2}}
Code is placed in correct format, however empty fields get filled with 'null':
receivers:
test1:
test2:
test3: null
test4: null
Is there any way to prevent this?
I am expecting correct templating without insterted null fields.
There are no fields inserted. The processor only replaces values that already exist with a different serialization that has the same semantics.
test3: in YAML without a value is parsed as having an empty scalar value. The YAML Core Schema defines the following for empty values:
Regular expression
Resolved to tag
null | Null | NULL | ~
tag:yaml.org,2002:null
/* Empty */
tag:yaml.org,2002:null
Since the empty value is resolved to have the tag !!null (which is a shorthand for the full form shown above), it is loaded as nil into Go.
When toYaml receives your data, it doesn't know that the nil values originated from empty scalars. It needs to choose one of the possible serializations and chooses null. This adheres to the YAML spec and is therefore correct behavior.
Any downstream processor that supports the Core Schema should process test3: null in the same way it processes test3: without value. Therefore there should be no problem.
If you want test3: to specifically have the empty string as value instead of null, write
test3: ""
If you want it to contain an empty mapping, write
test3: {}

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.

Golang yaml unmarshal structure

I would need some help to handle configuration files in golang.
I renamed every fields and values for privacy (just saying)
I have this yaml configuration file :
Label1:
field1: value1
field2: value2
field3: value3
field4: value4
Label2:
field1: value1
field2: value2
field3: value3
field4: value4
Label3:
field1: value1
field2: value2
field3: value3
field4: value4
I'm using https://github.com/kylelemons/go-gypsy/tree/master/yaml to manually decode this yaml file into the structure below (manually walking the list of nodes). I don't have control over how many "Label" items will be on that file so I need a generic way of parsing it (and it is generic using the library mentioned above)
type Obj struct {
Field1 string `yaml:"field1"`
Field2 string `yaml:"field2"`
Field3 string `yaml:"field3"`
Field4 bool `yaml:"field4"`
}
type ObjConfig struct {
Objs map[string]Obj
}
I have several other configuration files, much simpler, which I'm able to decode using annotations such as :
type conf1 struct {
Field1 int `yaml:"field1"`
Field2 string `yaml:"field2"`
}
I'm using the automatic yaml Unmarshal (through Viper framework) for these and it's working fine.
It wasn't a big deal mixing these 2 ways of handling configuration files until now. But now I need to retrieve the file from a spring config server that I did set up instead of having the files locally. I'm using this library to do so :
https://github.com/Piszmog/cloudconfigclient
It's working well for structures annotated with the yaml:"fieldX", I'm able to deserialize it directly.
But for the first structure of course it's not working and I need a workaround. The library (cloudconfigclient) is using the classic yaml decoder so I can't write my own custom decoder. Looking at the library code it uses this code to deserialize the configuration file (with resp.Body being the yaml configuration file content) :
var dest interface{}
yaml.NewDecoder(resp.Body).Decode(dest)
I'm able to change the configuraton file structure though, as long as I can get the same data in it. Maybe I could use something like
Labels:
- Label1:
field1: value1
field2:value2
....
- Label2:
field1:value1
....
and use the yaml map handling from unmarshal ?
I'm obviously not experienced with golang, I'd love to get some help here.
To sum up, the question is how to decode the first yaml file using yaml.Unmarshal with the classic decoder (by either specific annotations that I don't know of, or changing the yaml structure itself).
I got it working by mapping it to a generic map[string]interface{} type
var configResponse map[string]interface{}
err = configClient.GetFileFromBranch(BRANCH, CONF_DIR, CONF_FILE, &configResponse )
and then handling the cast myself into the structure
type ObjConfig struct {
Objs map[string]Obj
}
Not the most easy to read nor resilient to error solution but it's working

Google Workflows: How to get part of a string?

In the following workflow I want to return part of a string, for example:
- define:
assign:
- value: foobar
- returnValue:
return: ${value}
This would return foobar how would I return just foo?
This feature is now supported under the text library.
You can get part of the string using ${text.substring(value), 0, 3}

Can't evaluate field <field> in type string

I'm used text/template in golang package to parse text with environment in json string.
Example: https://play.golang.org/p/uARnrOyG4Th
But I have an error: 2009/11/10 23:00:00 Execute: template: Person template:1:19: executing "Person template" at <.id>: can't evaluate field id in type string
Please help me with problem. I couldn't find the error based on the library's documents.
template can't directly apply to string, you should create a struct then unmarshal your JSON string to the struct instance. try the code
person := map[string]string{"id": "12345", "token": "NSJACSCS"}
output:
momo://pay?appid=12345&token=NSJACSCS
Program exited.

Resources