F5Networks / f5-appsvcs-extension

F5 BIG-IP Application Services 3 Extension
Apache License 2.0
163 stars 52 forks source link

AS3 schema does not support per app declarations #810

Open sohel-m opened 3 months ago

sohel-m commented 3 months ago

Environment

Summary

The current json schema is not able to validate per-app declarations. I see from the releases page that per-app was introduced as beta feature in 3.47.0; but maybe the as3 schema has not been updated to accommodate it yet. From some communications I see that per-app will be available as General Availability in 3.50.0, we need a way to verify the json schema for perapp declarations as well :)

I know 3.50.0 is still not "released" according to releases, so maybe this issue has been prematurely raised.

Steps To Reproduce

Steps to reproduce the behavior: Get the sample per-app declaration from user guide: https://clouddocs.f5.com/products/extensions/f5-appsvcs-extension/latest/userguide/per-app-declarations.html#example-per-application-declaration

Get the latest up to date schema: https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/main/schema/3.50.0/as3-schema-3.50.0-5.json

  1. Validate locally below declaration
    {
    "$schema": "https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/main/schema/3.50.0/as3-schema-3.50.0-5.json",
    "id": "per-app-declaration",
    "schemaVersion": "3.50.0",
    "controls": {
        "class": "Controls",
        "logLevel": "debug",
        "trace": true
    },
    "Application1": {
        "class": "Application",
        "service": {
            "class": "Service_HTTP",
            "virtualAddresses": [
                "192.0.2.1"
            ],
            "pool": "pool"
        },
        "pool": {
            "class": "Pool",
            "members": [
                {
                    "servicePort": 80,
                    "serverAddresses": [
                        "192.0.2.10",
                        "192.0.2.20"
                    ]
                }
            ]
        }
    }
    }

Expected Behavior

The sample per-app AS3 declaration should have been validated by the schema

Actual Behavior

The json schema validation fails :(

tpitkinf5 commented 3 months ago

Hi @sohel-m, could you post the validation failure that you're seeing? And just to verify, you're posting to /appsvcs/declare/<tenant>/applications? The standard /appsvcs/declare endpoint expects a full, tenant-level declaration and will fail validation if it receives a per-app request.

sohel-m commented 3 months ago

Hello @tpitkinf5 I am not validating against the F5 BIGIP actually. So not interacting with "/appsvcs/declare" or "/appsvcs/declare//applications" at all :)

I am doing a local json schema validation using the json schema provided by F5. (This is part of some prechecks that we do in our pipeline)

It can be easily done by your IDE like VScode as well by just loading the file or using standard json schema validation libraries like:

In my case I'm using the ansible module for validating but I think that's is irrelevant to the topic.

What I have found is that the schema file works for validating tenant level declarations, but does not work for per-app declarations :( One of the errors is for the top level Application class declaration like: Value must be "Tenant"

tpitkinf5 commented 3 months ago

Ah, I now see where I missed that part in your original description about locally validating. Sorry about the confusion and thank you for clearing that up for me.

Unfortunately the schema that's provided in the schema/<version> directory is the top-level schema that the /declare endpoint validates declarations against in AS3. There is a separate per-app schema that exists in this repository, but it's a bit harder to find and validate against in its current state.

To locally validate against the per-apps schema, you'll need to clone this repository and build the desired schema. The following steps will walk you through the process:

  1. Clone the repository onto your local machine
  2. Build the adc-schema.json schema file with the following command from the root directory of the project: node scripts/build/schema-build.js. This script combines a number of individual schemas into a single schema file, which can be found at src/schema/latest/adc-schema.json. This file will be referenced by the per-app schema.
  3. Use the src/schema/latest/app-schema.json schema file to locally validate against your declaration

Note: The app-schema.json schema file externally references the adc-schema.json schema file that you built in step 2. Depending on what tool you use to validate schemas with, you may need to provide/load both schemas.

I hope this helps!

sohel-m commented 3 months ago

Thanks for your reply and the detailed workaround/instructions to get the per-app schema @tpitkinf5 :)

I'm wondering if there is a possibility on your side to somehow implement one of the following two options

(I'm a complete novice in the https://json-schema.org/ topic so I'm unsure about the feasibility of my requests)

  1. Have a common/(bundled ?) schema which is able to validate both AS3 modes of deployment(tenant-based and app-based)
  2. 'Officially' host a per-app schema file along with the current tenant/top-level schema in the repository which can be used in a similar fashion as the latter.

Meanwhile I'll start some testing according the process you explained, thanks again for that

Cheers

tpitkinf5 commented 3 months ago

I agree that providing some type of easily accessible version of the per-app schema in the /schema/<version> directory is the correct solution for this issue. And the two options that you mentioned line up with what I was envisioning as well:

  1. Bundling the per-app schema inside the as3-schema.json file is possible and provides a single file that can validate both types of requests. The only downside to this approach is that a JSON schema validation tool would no longer be able to determine if you wanted to validate against the tenant level schema or app level schema. So if your declaration fails all possible schemas, you'd end up with a large number of validation errors due to the tool trying to validate against all logical paths. It's not a blocker, but worth nothing.
  2. Providing a separate per-app schema file in the /schema/<version> directory and either referencing or duplicating the necessary as3-schema.json file data is also possible. This would allow you to define what specific schema you'd like to validate against (tenant or app level) by loading the appropriate file(s) into the validation tool.

I'd recommend keeping this issue open so that @sunitharonan can triage this and track it internally. In the meantime, I hope that the workaround of building the schema from the repository's source code works for you.

sohel-m commented 3 months ago

Hi @tpitkinf5

Thanks for acknowledging the issue.

I agree with your assessment of (1) that we can have large number of validation errors in case of an invalid declaration which could leave a user more astray than close to rectifying it because of all the possible logical paths. Following that, bundling might not be the way to go ahead, and its better to have a separate per-app json schema file.

On my side I was unable to build the schema locally :( I think its because some dependencies are not public? This is what I got when trying to install deps before running build script.

npm ERR! code ENOTFOUND
npm ERR! syscall getaddrinfo
npm ERR! errno ENOTFOUND
npm ERR! network request to
https://${artifactory_url}/artifactory/api/npm/f5-automation-toolchain-npm/@automation-toolchain%2ff5-appsvcs-schema
failed, reason: getaddrinfo ENOTFOUND ${artifactory_url}
npm ERR! network This is a problem related to network connectivity.

In any case could you please attach the per-app schema(3.50.1) file to this case itself? :)

Until we have a more permanent solution by you or @sunitharonan where we have the schema in a more accessible place like schema/<version>/ directory?

Thanks once again

sohel-m commented 2 months ago

In any case could you please attach the per-app schema(3.50.1) file to this case itself? :)

Umm, @tpitkinf5 could you please help with above?

Thanks in advance :)

tpitkinf5 commented 2 months ago

@sohel-m, sorry for the late reply and for providing you with instructions that couldn't be run on your local machine. I had forgotten about the private dependency that the schema build script relies on.

I'm currently requesting permission to attach the adc-schema.json file to this issue and will hopefully have a response and solution for you later today.

tpitkinf5 commented 2 months ago

Unfortunately I'm still waiting on that response and permission to attach the requested file.

But I do have an alternative solution for you that takes advantage of the JSON schema that you currently have access to. In fact, this alternative solution will probably be similar to what the permanent solution looks like. Here are the two steps:

1.) Copy the ./src/schema/latest/app-schema.json file to the ./schema/latest directory 2.) Update the newly copied app-schema.json file to reference the as3-schema.json file that's in the same schema folder. You can do this by replacing the two UUID $ref lines in the schema with the UUID of the as3-schema.json file:

                }
             ]
         },
-        "controls": { "$ref": "urn:uuid:f83d84a1-b27b-441a-ae32-314b3de3315a#/definitions/Controls" }
+        "controls": { "$ref": "urn:uuid:85626792-9ee7-46bb-8fc8-4ba708cfdc1d#/definitions/Controls" }
     },
     "additionalProperties": {
-        "$ref": "urn:uuid:f83d84a1-b27b-441a-ae32-314b3de3315a#/definitions/Application"
+        "$ref": "urn:uuid:85626792-9ee7-46bb-8fc8-4ba708cfdc1d#/definitions/Application"
     },
     "propertyNames": {
         "pattern": "^[A-Za-z][0-9A-Za-z_.-]*$",

Now you should be able to use the app-schema.json file to validate your per-app declaration with the same functionality that the build script would have provided you. The only difference is that it's using the as3-schema.json file for additional validation instead of the adc-schema.json file. This change is OK because the objects that are being referenced are identical in both schema files.

And like I mentioned previously, don't forget that you may need to provide/load both files (app-schema.json and as3-schema.json) in order for your validation tool to resolve the external references!

I'll keep an eye out for any responses to my request and get that adc-schema.json attached to the issue once I have permission, but this solution should provide you with the same validation behavior in the mean time.

sohel-m commented 2 months ago

Hello @tpitkinf5

Thanks for your update On my side for the time being I will rely on the workaround as you suggested. Actually this part is proving a bit troublesome for me to implement

you may need to provide/load both files in order for your validation tool to resolve the external references!

I have both app-schema.json and as3-schema.json locally I'm using this module for json schema validation: https://docs.ansible.com/ansible/latest/collections/ansible/utils/validate_module.html#ansible-collections-ansible-utils-validate-module

But I keep running into the issue of properly referencing the as3-schema.json from within app-schema.json. Similar issues faced by others: https://stackoverflow.com/questions/67198939/resolve-ref-by-relative-file-path https://stackoverflow.com/questions/22796063/referencing-a-local-relative-file-in-a-json-schema

The solutions relying on relative path resolution that seemed to have work for others doesn't seem to work for me :(

In any case I'll keep exploring how I can make the external references work :)

Could you explain what is the permanent solution you are targeting ? Can we have two independent schema files for tenant declarations and per-app declarations ? That way we could simply include those two files without worrying about external references

tpitkinf5 commented 2 months ago

Hello @sohel-m

I'm sorry to hear that the workaround is still causing trouble with your tooling.

AS3 uses the AJV tool for JSON schema validation, but I can see how other tools might not handle a URN external reference path based on how JSON schema files are loaded into the specific tool. I think you're on the right track by investigating how to reference an external file using a file URI instead of a URN.

I want to clarify that @mdditt2000 and @sunitharonan will handle triaging this task and discussing with the AS3 team on how this issue will be resolved. But I'll leave the following comment here for the team to review and consider:

Based on our discussion and the variety of different JSON schema validation tools, I agree that the permanent solution should be an independent, stand-alone per-app schema to help simplify the experience of locally validating. Creating the stand-alone schema file would involve:

  1. Copying the ./src/schema/latest/app-schema.json file to the ./schema/latest directory
  2. Copying the definitions object from the as3-schema.json file into the new app-schema.json file.
  3. Updating the new app-schema.json file to reference the necessary objects in the same file:

    
                }
             ]
         },
    -        "controls": { "$ref": "urn:uuid:f83d84a1-b27b-441a-ae32-314b3de3315a#/definitions/Controls" }
    +        "controls": { "$ref": "#/definitions/Controls" }
     },
     "additionalProperties": {
    -        "$ref": "urn:uuid:f83d84a1-b27b-441a-ae32-314b3de3315a#/definitions/Application"
    +        "$ref": "#/definitions/Application"
     },
     "propertyNames": {
         "pattern": "^[A-Za-z][0-9A-Za-z_.-]*$",
sohel-m commented 2 months ago

Thanks for your response Tom. I have managed to workaround in a similar manner as you have suggested. I will keep watching this issue for whatever permanent solution is decided :)