How to use conditions in OpenAPI Generator's Mustache templates? - openapi

I'm using OAS3 generator for Java as a Maven plugin to generate POJOs, controllers, delegates etc for my APIs with the Mustache templates from the openapi-generator repository: https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache
I'm trying to edit this template so that the "#Controller" annotation is generated only if a condition is met. I've searched for multiple solutions for this and one of them was using "vendorExtensions".
I've made the following contract with x-generateController vendorExtension:
openapi: 3.0.0
info:
title: User API
description: API for user changes
contact:
name: xxx
url: xxx
email: xxx
license:
name: xxx
url: xxx
version: 1.0.0
tags:
- name: user
x-generateController: True
paths:
/users:
...
And then in the Mustache template file I have put the following:
{{#vendorExtensions.x-generateController}}
#Controller("{{classname}}")
{{/vendorExtensions.x-generateController}}
The generator works just fine without this condition but it seems like it doesn't take into account x-generateController. In fact, if I try to just place it as a comment like this:
// {{vendorExtensions.x-generateController}}
I get only "// " and an empty space. I've also tried putting it at the "endpoint level" and not in the "info level" and the problem is the same.
Is there anything more that I should've done in the configuration? Is there any alternative for a condition in the Mustache template?

Related

FOSRestBundle routes versioning

I wanted to implement versioning of endpoints for my project.. turns out the FOSRestBundle implementation is not quite clear so I wanted to implement like follow:
Symfony 5.4
FOSRestBundle 3
see below annotation.yaml file:
v2_controllers:
resource: ../../src/Controller/V2/
type: annotation
prefix: /v2
name_prefix: 'api_v2_'
controllers:
resource: ../../src/Controller/
type: annotation
name_prefix: 'api_'
kernel:
resource: ../../src/Kernel.php
type: annotation
when I run this command php bin/console debug:router --show-controllers
I get the following result:
..
..
...
api_offer_list GET ANY ANY /offer-list/{productId}/{pageType}/ App\Controller\V2\OfferListV2Controller::offerListAction()
api_v2_offer_list GET ANY ANY /v2/offer-list/{productId}/{pageType}/ App\Controller\V2\OfferListV2Controller::offerListAction()
...
..
You can see that the new version is also overriding the older endpoint for some weird reasons
and finally here's my fos_rest.yaml config:
# Read the documentation: https://symfony.com/doc/master/bundles/FOSRestBundle/index.html
fos_rest:
param_fetcher_listener: true
Inside the controller directory, you need to create two separate directories, one for v1 and the other for v2 and this should solve the problem.
Controller/
v1/
v2/

Github issue form: add label based on dropdown

I'm currently looking at the new YAML based issue templates at Github and would like to achieve a system where a label is assigned to the issue dependent on the value the issue creator selects from a dropdown.
I couldn't find anything on this.
For example I have the following bug template:
name: Bug Report
description: File a bug report
labels: [triage]
body:
- type: dropdown
id: bug-type
attributes:
label: Project
multiple: true
options:
- API
- WebUI
validations:
required: true
How could I add a label "api" and/or "webui" based on the selection of the dropdown?

Is it possible to reference a single path and method in OpenAPI 3?

Suppose I have an OpenAPI 3 document describing API Foo as follows:
openapi: 3.0.0
info:
version: '1'
title: Foo
paths:
/foo:
get:
responses:
200:
description: A Foo
post:
responses:
201:
description: Foo created
In another OpenAPI document for API Bar, I would like to reference only the GET /foo operation from API Foo. The OpenAPI docs talk a little about referencing a whole path. However, if I do the following:
openapi: 3.0.0
info:
version: '1'
title: Bar
paths:
/foo:
$ref: 'foo.yaml#/paths/~1foo'
I naturally get both the GET and the POST in API Bar, since only the path is referenced, not the method.
I tried this:
openapi: 3.0.0
info:
version: '1'
title: Bar
paths:
/foo:
get:
$ref: 'foo.yaml#/paths/~1foo/get'
But this gives errors like should NOT have additional properties additionalProperty: $ref and should have required property 'responses' missingProperty: responses in various tools, so it doesn't seem to be supported.
Is there a way to accomplish this? I should note that the real request is much more complicated, hence the desire to de-duplicate. If possible I would like to avoid filling in many child objects of get with individual $refs.
OpenAPI doesn't have a way to $ref an individual operation (get/post/etc.), you can only $ref an entire path.
You can propose syntax enhancements in the OpenAPI Specification repository:
https://github.com/OAI/OpenAPI-Specification/issues

Do AWS-SAM templates support lifecycleconfiguration settings?

Does anyone know if SAM templates support Lifecycleconfigruation settings? I see within standard cloudformation definitions you can define the lifecycle of objects like:
BucketName: "Mys3Bucket"
LifecycleConfiguration:
Rules:
- AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
Status: Enabled
- ExpirationInDays: 14
...
But this seems to fail when used in a SAM template. Am I doing something wrong or is this not part of the serverless application model definition?
It works for me using the SAM CLI 1.15.0, although documentation seems sparse (hence my landing on this question while trying to figure it out).
The SAM template snippet below successfully creates a bucket and sets an appropriate lifecycle rule.
Resources:
Bucket1:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Sub "${BucketName}"
AccessControl: Private
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- ExpirationInDays: 6
Status: Enabled

run ansible task only if tag is NOT specified

Say I want to run a task only when a specific tag is NOT in the list of tags supplied on the command line, even if other tags are specified. Of these, only the last one will work as I expect in all situations:
- hosts: all
tasks:
- debug:
msg: 'not TAG (won't work if other tags specified)'
tags: not TAG
- debug:
msg: 'always, but not if TAG specified (doesn't work; always runs)'
tags: always,not TAG
- debug:
msg: 'ALWAYS, but not if TAG in ansible_run_tags'
when: "'TAG' not in ansible_run_tags"
tags: always
Try it with different CLI options and you'll hopefully see why I find this a bit perplexing:
ansible-playbook tags-test.yml -l HOST
ansible-playbook tags-test.yml -l HOST -t TAG
ansible-playbook tags-test.yml -l HOST -t OTHERTAG
Questions: (a) is that expected behavior? and (b) is there a better way or some logic I'm missing?
I'm surprised I had to dig into the (undocumented, AFAICT) variable ansible_run_tags.
Amendment: It was suggested that I post my actual use case. I'm using ansible to drive system updates on Debian family systems. I'm trying to notify at the end if a reboot is required unless the tag reboot was supplied, in which case cause a reboot (and wait for system to come back up). Here is the relevant snippet:
- name: check and perhaps reboot
block:
- name: Check if a reboot is required
stat:
path: /var/run/reboot-required
get_md5: no
register: reboot
tags: always,reboot
- name: Alert if a reboot is required
fail:
msg: "NOTE: a reboot required to finish uppdates."
when:
- ('reboot' not in ansible_run_tags)
- reboot.stat.exists
tags: always
- name: Reboot the server
reboot:
msg: rebooting after Ansible applied system updates
when: reboot.stat.exists or ('force-reboot' in ansible_run_tags)
tags: never,reboot,force-reboot
I think my original question(s) still have merit, but I'm also willing to accept alternative methods of accomplishing this same functionality.
For completeness, and since only #paul-sweeney has offered any alternative solution, I'll answer my own question with my current best solution and let people pick / up-vote their favorite:
---
- name: run only if 'TAG' not specified
debug:
msg: 'ALWAYS, but not if TAG in ansible_run_tags'
when: "'TAG' not in ansible_run_tags"
tags: always
I know it's an old(ish) question, but I had a similar requirement.
It's probably something best implemented another way ... but ... sometimes it can be useful.
I'd achieve it by setting a fact if the tag IS specified, then outputting the message only if the fact is not set, something like:
---
- name: "test task runs only if tag missing"
hosts: all
tasks:
- name: "suppress message if tag given"
set_fact: suppress_message=yes
tags: reboot,never
- name: "message"
debug:
msg: "You didn't say 'reboot'"
when: suppress_message is not defined
I think that we have states for controlling (example: started, restarted, stopped), states for installing (present,absent) and components (webserver, db,...).
Ansible is lacking a good separation of those 3 dimensions and mixing those 3 dimensions in a single tag system is leading to confusion.
For example, if you have a 'webserver' and a 'DB' tag, you want to 'restart' the DB and not the webserver using a 'restart' tag.
But it won't work if the 'restart' tasks of the DB and the webserver are in the same tasks file with the same 'restart' tag as the 'restart' tag will start both the DB and the webserver...
So you will have probably to separate webserver and DB tasks in 2 separate files and use the tag at the level of the include.
Using tags means that you have a tree of options, not a matrix of options.
I like the tag concept but the fact that it is not possible to use it in conditional expressions is making it less appealing.
What I recommend is to declare tags in a role but map them into variables as a first task. So the 'restart' and 'db' tags would become boolean variables in my role and use when: instead of tags:
ansible-playbook has a skip-tags option. The example from the docs is
ansible-playbook example.yml --skip-tags "packages"
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_tags.html