Skip to content

Conversation

@d3flex
Copy link
Contributor

@d3flex d3flex commented Sep 11, 2025

There are two commits with the very basic changes.
which provides:

  • validation on requests
  • validation on responses

Two packages are required cpanm Mojolicious::Plugin::OpenAPI and
cpanm Mojolicious::Plugin::SwaggerUI. Remove the lines in the Setup for the second if you do not need it for now.
If not, when you start the server you should see the API documentation with the Swagger UI (go to http://127.0.0.1/api/docs)

My understanding is that there are two ways to perform the validation. this is the not-automatic way.
You can ignore the components section as well. it is not used.

Signed-off-by: Ioannis Bonatakis <[email protected]>
define a spec file for openapi and configure the plugin in the server. it
requires . The commit shows a manual validation
of the inputs.

Signed-off-by: Ioannis Bonatakis <[email protected]>
@d3flex d3flex added the RFC label Sep 11, 2025
Copy link
Contributor

@perlpunk perlpunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, good :)

Now please put yourself in the shoes of the person picking up the followup ticket and looking at all the commented out stuff and also the not commented out stuff that is not needed.

A proof of concept doesn't need to pass all tests, and it can also have commented out parts, but please clean up the not needed parts that don't serve any purpose for what we want. I think it will look much cleaner then, and then we can concentrate on the things that are left.

See individual comments.

Comment on lines +83 to +84
#$self->openapi->valid_input or return;
#my $validation = $self->openapi->validator;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

=cut

sub show ($self) {
# manually triggers validation - unclear if this is how it should be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the comment. That's how it should work.

$job = $job->to_hash(assets => 1, check_assets => $check_assets, deps => 1, details => $details, parent_group => 1);
$job->{followed_id} = $job_id if ($job_id != $job->{id});
$self->render(json => {job => $job});
$self->render(openapi => {job => $job});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this you are telling the plugin to validate the response.
We said that we don't want this for now (we can always add it later).
If you remove this change, you can also remove the responses parts from the yaml file.


sub prio ($self) {

# seems this is the default behavior
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Comment on lines +505 to +506
#my $v = $self->validation;
#my $prio = $v->required('prio')->num->param;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

Comment on lines +23 to +24
operationId: apiv1_job
x-mojo-name: apiv1_job
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need only one of those two

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, operationId is not required. is not one or the other. operationId can be used for some more advanced stuff (like links), but it has to be unique. here I use the same as x-mojo-name but I think it is not unique in WebAPI.pm

Comment on lines +33 to +69
responses:
'200':
description: A successful response.
content:
application/json:
schema:
type: object
properties:
jobs:
type: array
items: {}
'404':
description: 'Not Found.'
content:
application/json:
schema:
type: object
example: 'Scheduled product to clone settings from not found.'
properties:
error:
type: string
# '400':
# description: Erroneous parameters (key invalid, list_value invalid)
# content:
# application/json:
# schema:
# type: object
# properties:
# error_status:
# type: integer
# error:
# type: string
# example: Erroneous parameters (key invalid, list_value invalid)
# text/plain:
# schema:
# type: string
# example: Erroneous parameters (key invalid, list_value invalid)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

Comment on lines +87 to +91
# - $ref: '#/components/parameters/CSRFHeader'
# - in: cookie
# name: csrftoken
# schema:
# type: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

Comment on lines +107 to +138
responses:
'200':
description: 'OK. The jobs were scheduled synchronously.'
content:
application/json:
schema:
#$ref: '#/components/schemas/IsoSyncResponse'
type: object
properties:
result:
#type: {} #???????
description: 'True if the update was successful'
# '202':
# description: 'Accepted. The job scheduling was enqueued to run asynchronously.'
# content:
# application/json:
# schema:
# $ref: '#/components/schemas/IsoAsyncResponse'
# '400':
# description: 'Bad Request with something is missing or invalid.'
# content:
# application/json:
# schema:
# type: string
# example: 'Specified scheduled_product_id is invalid.'
# '404':
# description: 'Not Found.'
# content:
# text/plain:
# schema:
# type: string
# example: 'Scheduled product to clone settings from not found.'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

Comment on lines +139 to +230
components:
parameters:
CSRFHeader:
name: X-Requested-With
in: header
description: 'Required header to bypass CSRF check for API clients.'
required: true
schema:
type: string
default: XMLHttpRequest
securitySchemes:
basicAuth:
type: http
scheme: basic
description: "HTTP Basic Authentication using your username and a composite password of 'API_KEY:API_SECRET'."
oauth2Auth:
type: oauth2
flows:
implicit:
authorizationUrl: https://id.opensuse.org/login/ldap
scopes:
admin: admin
operator: operator
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT # optional, arbitrary value for documentation purposes
schemas:
isosSync:
type: object
required:
- DISTRI
- VERSION
- FLAVOR
- ARCH
properties:
DISTRI:
type: string
description: 'The Linux distribution.'
example: 'opensuse'
VERSION:
type: string
description: 'The distribution version.'
example: '15.4'
FLAVOR:
type: string
description: 'The build flavor, e.g., DVD, Live, etc.'
example: 'DVD'
ARCH:
type: string
description: 'The processor architecture.'
example: 'x86_64'
async:
type: boolean
description: 'If true, the operation runs as a background job.'

isosAsync:
type: object
required:
- scheduled_product_clone_id
properties:
scheduled_product_clone_id:
type: integer
description: 'ID of a previous product to clone settings from.'
example: 12345
async:
type: boolean
description: 'If true, the operation runs as a background job.'
additionalProperties: {}

IsoSyncResponse:
type: object
properties:
scheduled_product_id:
type: integer
count:
type: integer
ids:
type: array
items:
type: integer
failed:
type: object
additionalProperties: true

IsoAsyncResponse:
type: object
properties:
job_id:
type: integer
scheduled_product_id:
type: integer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

my $r = $self->routes->namespaces(
[
'OpenQA::Shared::Controller', 'OpenQA::WebAPI::Controller',
'OpenQA::WebAPI', 'OpenQA::WebAPI::Controller::API::V1'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering about this one. Cc @kraih @Martchus
We need this so that the OpenAPI plugin can find the controllers.
But could this have any other implications to add this as a "global" namespace?
Currently we explicitly route to that namespace in WebAPI.pm for the api routes.
I couldn't find any configuration option in the OpenAPI plugin to configure a namespace.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we cannot specify the namespace (and just specify the controller/method via e.g. x-mojo-to: 'job#show') then we have to make sure that the names of the controller packages are unique. Probably not a big deal. Probably it wouldn't be hard to extend the plugin to allow specifying e.g. x-mojo-ns: 'OpenQA::WebAPI::Controller::API::V1' to avoid this.

@d3flex
Copy link
Contributor Author

d3flex commented Sep 11, 2025

I am not sure why this gets reviews. I will close it but I will try to answer general question wherever I can.

@d3flex d3flex closed this Sep 11, 2025
@perlpunk perlpunk reopened this Sep 11, 2025
@perlpunk
Copy link
Contributor

Please leave it open for now, so it is visible for people, and please address the requested changes

@d3flex
Copy link
Contributor Author

d3flex commented Sep 11, 2025

Please leave it open for now, so it is visible for people, and please address the requested changes

I wish to leave it as is. I do not expect this to ever merged and I wouldnt like to spend more time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants