opensearch-project / opensearch-api-specification

API specification for OpenSearch
Apache License 2.0
33 stars 62 forks source link

[BUG] Trying APIs on opensearch-project.github.io/opensearch-api-specification is broken #216

Open dblock opened 7 months ago

dblock commented 7 months ago

What is the bug?

Try invoking an API in https://opensearch-project.github.io/opensearch-api-specification/. It fails because it thinks OpenSearch is running on https://opensearch-project.github.io.

What is the expected behavior?

Connect https://opensearch-project.github.io/opensearch-api-specification/ to https://playground.opensearch.org so that APIs can be attempted.

Do you have any screenshots?

Screenshot 2024-04-03 at 11 47 05 AM

prudhvigodithi commented 7 months ago

Hey @dblock following this Dockerfile I was able to install the plugin opensearch-api-2.12.0.0.zip and invoke the URL https://127.0.0.1:9200/_plugins/api which works fine, do you know the endpoint to get the above screen you posted in the description? with https://127.0.0.1:9200/opensearch-api-specification/ I get the error as

{"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index [opensearch-api-specification]","index":"opensearch-api-specification","resource.id":"opensearch-api-specification","resource.type":"index_or_alias","index_uuid":"_na_"}],"type":"index_not_found_exception","reason":"no such index [opensearch-api-specification]","index":"opensearch-api-specification","resource.id":"opensearch-api-specification","resource.type":"index_or_alias","index_uuid":"_na_"},"status":404}
prudhvigodithi commented 7 months ago

I understood now, the swagger endpoint is coming from https://github.com/opensearch-project/opensearch-api-specification/blob/main/index.html and served with jekyll, not with opensearch-api-2.12.0.0.zip plugin.

dblock commented 7 months ago

@prudhvigodithi That is correct. This issue has nothing to do with the opensearch-api-2.12.0.0.zip plugin.

prudhvigodithi commented 7 months ago

Thanks for confirming @dblock, how about we integrate Swagger into an opensearch-api plugin and provide comprehensive documentation with a user-friendly interface for interacting with OpenSearch API?. Once we have this it would be straight forward to install the plugin the in https://playground.opensearch.org/ and expose the Swagger UI using kubernetes ingress path.

Another approach would be updating the url https://github.com/opensearch-project/opensearch-api-specification/blob/main/index.html#L14 here with https://playground.opensearch.org/_plugins/api (make sure the opensearch-api plugin is installed) and access directly from the repo GH pages URL https://opensearch-project.github.io/opensearch-api-specification/.

Adding @bbarani @Flyingliuhub

dblock commented 7 months ago

Thanks for confirming @dblock, how about we integrate Swagger into an opensearch-api plugin and provide comprehensive documentation with a user-friendly interface for interacting with OpenSearch API?.

This is a really good idea. I opened https://github.com/dblock/opensearch-api/issues/3.

However, to fix this particular issue I'd prefer if we made jekyll build (this code) write https://playground.opensearch.org/ in the right places and enable CORS on https://playground.opensearch.org. Seems simpler, no?

prudhvigodithi commented 7 months ago

However, to fix this particular issue I'd prefer if we made jekyll build (this code) write https://playground.opensearch.org/ in the right places and enable CORS on https://playground.opensearch.org. Seems simpler, no?

Yes dB that should work as well, only thing we need to make sure is the API's part of opensearch-openapi.yaml should be same and supported by https://playground.opensearch.org/ (to avoid issues with API change with versioning). To achieve this we just need to update the CORS settings of the cluster and update the opensearch-openapi.yaml with request URL.

Option 1:

Add the following settings to playground cluster opensearch.yml, the http.cors.allow-origin can be better secured to avoid *.

http.cors.enabled : true
http.cors.allow-origin: "*"
http.cors.allow-methods: OPTIONS,HEAD,GET,POST,PUT,DELETE
http.cors.allow-headers: X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization  

Update the opensearch-openapi.yaml with request URL server (example as follows)

openapi: 3.1.0
info:
  title: OpenSearch API
  description: OpenSearch API
  version: 1.0.0
servers:
  - url: http://localhost:9200 ## Replace with the playground URL
paths:
  /:
  .
  .
  .

Now with jekyll serve swagger UI should have the passed in server (playground) URL for users to test (we should handle the username and password securely during the request invoke).

Screenshot 2024-04-08 at 7 43 05 PM

Option 2:

But if the plugin opensearch-api has the swagger UI along with _plugins/api we just need to add the following in index.html to dynamically fetch the cluster API's along with swagger UI and test the API's.

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>OpenSearch API Spec</title>
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
</head>

<body>
    <div id="swagger-ui"></div>
    <script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
    <script>
        window.onload = function () {
            // Basic Authentication credentials
            var username = 'admin';
            var password = 'myStrongPassword123@456';
            var basicAuthHeader = 'Basic ' + btoa(username + ':' + password);

            // API URL
            var apiUrl = 'http://localhost:9200/_plugins/api';
            fetch(apiUrl, {
                method: 'GET',
                headers: {
                    'Authorization': basicAuthHeader
                }
            })
            .then(function(response) {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.json();
            })
            .then(function(data) {
                // Fix paths in the API specification
                fixPaths(data);

                const ui = SwaggerUIBundle({
                    spec: data,
                    dom_id: '#swagger-ui',
                    deepLinking: true,
                    presets: [
                        SwaggerUIBundle.presets.apis,
                        SwaggerUIBundle.SwaggerUIStandalonePreset
                    ],
                    plugins: [
                        SwaggerUIBundle.plugins.DownloadUrl
                    ],
                    requestInterceptor: function(request) {
                        request.headers.Authorization = basicAuthHeader;
                        return request;
                    }
                });
                window.ui = ui;
            })
            .catch(function(error) {
                console.error('Error fetching API:', error);
            });
        }

        function fixPaths(data) {
            for (var path in data.paths) {
                var fixedPath = path.replace(/__/g, "_");
                if (fixedPath !== path) {
                    data.paths[fixedPath] = data.paths[path];
                    delete data.paths[path];
                }
            }
        }
    </script>
</body>

</html>
dblock commented 7 months ago

I like option 1. The spec is compatible with OpenSearch 2.x.

Option 2 requires changes to the plugin, the plugin to be installed, and so on, which seems like a lot of work for something we can achieve with option 1.

dblock commented 7 months ago

@prudhvigodithi Are you going to try and implement this?

prudhvigodithi commented 7 months ago

Once we have the CORS enabled and a secure credential for authentication from https://playground.opensearch.org/ we can then come back to modify the opensearch-api-specification swagger setup to talk to playground. @dblock I can contribute to opensearch-api-specification swagger setup but need some changes from https://playground.opensearch.org/ cluster, adding @Flyingliuhub to take a look. @bbarani.

dblock commented 5 months ago

@prudhvigodithi @Flyingliuhub Is this something that we can do? Is there a GitHub issue for CORS/auth?

Flyingliuhub commented 5 months ago

@prudhvigodithi @Flyingliuhub Is this something that we can do? Is there a GitHub issue for CORS/auth?

@prudhvigodithi , let's discuss and see what we can do here.

prudhvigodithi commented 5 months ago

Sure @Flyingliuhub.

dblock commented 3 weeks ago

@prudhvigodithi @Flyingliuhub Any way we can move this forward?