How to make my swagger curl match my apache config?

32 Views Asked by At

I'm running flask restx behind gunicorn and apache. My team only gets one server for all our tools so it's kind of necessary.

But in order to work w/ port 443 and https, I'm having to proxy my requests through apache and gunicorn. Apache config:

<VirtualHost *:443>
  ServerName webdev02.mycompany.com

  ## Vhost docroot
  DocumentRoot "/etc/httpd/htdocs"

  <Directory "/etc/httpd/htdocs">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  ## Logging
  ErrorLog "/var/log/httpd/httpd_error_log"
  ServerSignature Off
  CustomLog "/var/log/httpd/httpd_access_log" "mainserver"

  ## Server aliases
  ServerAlias webdev02.mycompany.com

  ## Custom fragment
  ## Custom fragment
  SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
  CustomLog "/var/log/httpd/httpd_access_log" combined env=!forwarded
  CustomLog "/var/log/httpd/httpd_access_log" proxy env=forwarded
<Location "literally 11 other applications">
  RequestHeader set X-Forwarded-Port 443
  ProxyPass http://127.0.0.1:80##/
</Location>
<Location /my_application>
  ProxyPass http://127.0.0.1:8082/
</Location>
<Location /swaggerui> # this has to be done to find the swaggerui page
  ProxyPass http://127.0.0.1:8082/swaggerui
</Location>
<Location /swagger.json> # because my_application represents the project running on port 8082, I have to redirect here to retrieve the swagger.json file
  ProxyPass http://webdev02.mycompany.com/my_application/swagger.json
</Location>
<Location /hosts/> # this is the start of my problems
  ProxyPass http://webdev02.mycompany.com/my_application/hosts/
</Location>
  SetEnv HTTPS On

</VirtualHost>

Flask code:

#main.py
from flask import Flask
from api_model import api
from api_view import namespace
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_port=1, x_for=1, x_host=1, x_prefix=1)
api.init_app(app)
api.add_namespace(namespace)

#api_view.py
from flask import request
from flask_restx import Namespace, Resource
from api_controller import ApiController
from api_model import host_get_model, host_put_model_send, host_put_model_return, host_fail_model
controller = ApiController()

namespace = Namespace('hosts', 'host endpoints')


@namespace.route('/<vmname>')
class Host(Resource):
    """Read, update and delete a specific host"""

    # @namespace.response(204, 'host not found')
    @namespace.response(500, 'Internal Server error')
    @namespace.marshal_with(host_get_model, mask='')
    def get(self, vmname):
        """Get host information"""
        arguments = {"vmname": vmname}
        result, status_code = controller.get_host_from_db(arguments)
        return result, status_code


@namespace.route('/')
class Host(Resource):
    @namespace.expect(host_put_model_send, validate=True)
    @namespace.marshal_with(host_put_model_return, mask='')
    def put(self):
        """Update host information"""
        data = request.json
        arguments = {"vmname": data["vmname"], "patchwindow": data["PatchWindow"]}
        result, status_code = controller.update_host_from_db(arguments)
        return result, status_code
    
#api_model.py
from flask_restx import fields, Api
api = Api(title="My_API", description="testing", doc="/")

host_get_model = api.model('host_get', {
    'vmname': fields.String(
        required=True,
        example='localhost',
        description='Fully Qualified Domain Name of server'
    ),
    'OS': fields.String(
        readonly=True,
        example='Linux',
        description='OS Type. Currently just Linux is available'
    ),
    'PatchWindow': fields.String(
        readonly=True,
        example='Mon_1800',
        description='Current PatchWindow'
    )
})

A curl requests works like so:

curl -X 'GET' \
  'https://webdev02.mycompany.com/my_application/hosts/myserver.mycompany.com' \
  -H 'accept: application/json'
{"vmname": "myserver.mycompany.com", "OS": "Red Hat Enterprise Linux 8", "PatchWindow": "1_Mon_AM_6"}

the problem: my swagger page does not recognize that it is behind Apache and Gunicorn. When I go to my swagger doc page, select that same endpoint above and hit execute, it outputs the CURL like this:

curl -X 'GET' \
  'https://webdev02.mycompany.com/hosts/myserver.mycompany.com' \
  -H 'accept: application/json'

What do I need to do to get my swagger example to match the actual location I'm creating w/ Apache?

0

There are 0 best solutions below