Skip to content

Conversation

@lresende
Copy link
Collaborator

@lresende lresende commented Sep 19, 2018

There are a few commits here, mostly around Kerberos/SPNEGO and Integration Tests.
Also, bumping the version to 0.2.6 to perform a release with these changes to be used in Jupyter Enterprise Gateway.

Please review, but don't squash/merge.

Copy link
Member

@kevin-bates kevin-bates left a comment

Choose a reason for hiding this comment

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

This is really great Luciano - thanks! I just had a couple comments.

if self.address is None:
raise ConfigurationError('API address is not set')
elif self.port is None:
raise ConfigurationError('API port is not set')
Copy link
Member

Choose a reason for hiding this comment

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

We should probably add checks against None for address and port at the very end of the constructor to maintain parity.

Also, this is removing a property that allowed the user to get a connection to the particular server. Seems like that needs to be preserved unless we know there are no applications using that property.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch... added it back together with fixes for test cases that were failing

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, not finding where property http_conn was added back in. Please advise.

"""
def __init__(self, address=None, port=8042, timeout=30):
self.address, self.port, self.timeout = address, port, timeout
def __init__(self, address=None, port=8042, timeout=30, kerberosEnaled=False):
Copy link
Member

Choose a reason for hiding this comment

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

Please fix typo to kerberosEnabled

"""
def __init__(self, address=None, port=8088, timeout=30):
self.address, self.port, self.timeout = address, port, timeout
def __init__(self, address=None, port=8088, timeout=30, kerberosEnaled=False):
Copy link
Member

Choose a reason for hiding this comment

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

Please fix typo to kerberosEnabled

@lresende lresende force-pushed the security branch 10 times, most recently from 1db7505 to 5f72136 Compare September 20, 2018 04:45
@lresende
Copy link
Collaborator Author

There are still some dependency issues with the tests, around the SPNEGO dependency, I will try to figure that out tomorrow.

@coveralls
Copy link

coveralls commented Sep 20, 2018

Coverage Status

Coverage decreased (-4.4%) to 91.685% when pulling a21f612 on lresende:security into ad9a807 on toidi:master.

@lresende
Copy link
Collaborator Author

Ok, All good with the dependencies, it was a tox configuration issue.

setup.py Outdated
install_requires = install_requires,
install_requires = [
'requests>=2.7,<3.0',
'requests-kerberos==0.12.0',
Copy link
Collaborator

Choose a reason for hiding this comment

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

it's not a good idea to pin requirements here, as it may conflict with project wide requirements
perhaps, it's possible to specify in terms of >=, <=?

import requests
import requests_mock

from tests import TestCase
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wish I would use pytest for testing
But fine for now. I may find some time to update tests


client.request('/ololo', foo='bar')
def test_valid_request(self):
with requests_mock.mock() as requests_get_mock:
Copy link
Collaborator

Choose a reason for hiding this comment

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

perhaps, use requests_mock as a decorator?

tox.ini Outdated

[testenv]
deps =
requests
Copy link
Collaborator

Choose a reason for hiding this comment

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

please keep this list sorted

"""
def __init__(self, address=None, port=8088, timeout=30):
self.address, self.port, self.timeout = address, port, timeout
def __init__(self, address=None, port=8088, timeout=30, kerberosEnabled=False):
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't mix variable naming styles. Project follows pep8 convention

from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
import requests
Copy link
Collaborator

Choose a reason for hiding this comment

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

with requests it becomes so much easies 👍

if params:
path = api_path + '?' + params
params = query_args
api_endpoint = 'http://{}:{}{}'.format(self.address, self.port, api_path)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have a doubt about hardcoding http here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

enabling https requires some more work throughout the code, we could address that in the future

@ediskandarov-cur
Copy link
Collaborator

Thanks for the PR!
I'll look again tomorrow morning, as I'm sleepy now

.travis.yml Outdated
install:
- pip install tox coveralls
- pip install --upgrade setuptools pip
- pip install --upgrade requests requests_mock requests_kerberos tox coveralls
Copy link
Collaborator

Choose a reason for hiding this comment

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

these deps should be managed by tox

Copy link
Collaborator

Choose a reason for hiding this comment

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

except tox and coveralls

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
Copy link
Collaborator

Choose a reason for hiding this comment

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

is it possible to make integration tests as a part of CI process?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The integration tests require a running yarn, we could probably add docker, etc... let me create an issue to address that in the near future.

appstats = self.resourceManager.cluster_application_statistics()
pprint(appstats.data)
self.assertIsNotNone(appstats.data['appStatInfo'])
# TODO: test arguments
Copy link
Collaborator

Choose a reason for hiding this comment

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

remove TODO

@lresende
Copy link
Collaborator Author

@toidi and @kevin-bates All comments have been addressed, and a few issues created around the things that are really general enhancements and not added by these commits. Any other issues, otherwise I would like to add these commits to master and perform a release so I can use this in EG.

Copy link
Member

@kevin-bates kevin-bates left a comment

Choose a reason for hiding this comment

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

All looks good except I can't find where the http_conn property was restored.

if self.address is None:
raise ConfigurationError('API address is not set')
elif self.port is None:
raise ConfigurationError('API port is not set')
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, not finding where property http_conn was added back in. Please advise.

@lresende
Copy link
Collaborator Author

In BaseYarnAPI there is now

    def _validate_configuration(self):
        if self.address is None:
            raise ConfigurationError('API address is not set')
        elif self.port is None:
            raise ConfigurationError('API port is not set')

and also the validation tests in test/test_base.py are passing:

   def test_http_configuration(self):
        with requests_mock.mock() as requests_get_mock:
            requests_get_mock.get('/ololo', text=json.dumps(BaseYarnAPITestCase.success_response()))

            client = self.get_client()
            client.address = None
            client.port = 80

            with self.assertRaises(ConfigurationError):
                client.request('/ololo')

@lresende
Copy link
Collaborator Author

Also note that, because we moved to now use the requests package, we are not using http_connection anymore.

@lresende
Copy link
Collaborator Author

And yes, looking from the diffs are a little strange, so I had to go into the dif, find the base.py and show the file from the diff page. You can probably do the same from the commits list as well.

@kevin-bates
Copy link
Member

I understand we're not using http_connection any more, but http_conn was decorated as a property via @property and I had assumed that that meant it was publicly exposed - therefore a "contract". If that's not the case, then please ignore my comment/concern. I just don't know, nor can we really determine, if that property is in use elsewhere and, if so, that particular client will break after upgrading.

@lresende lresende force-pushed the security branch 2 times, most recently from cfc8b30 to 0df6fb7 Compare September 21, 2018 21:21
@lresende
Copy link
Collaborator Author

Ok, I now understand your question. This is indeed a breaking change, as the HTTP connection is now managed internally by requests package. How about naming the release 0.3.0 and updating the changelog to explicitly describe this breaking change:

0.3.0 Release
    - Add support for YARN endpoints protected by Kerberos/SPNEGO
    - Moved to `requests` package for REST API invocation
    - Remove `http_con` property, as connections are now managed by `requests` package

loc_args = (
('states', states),
('applicationTypes', applicationTypes))
('application_types', application_types))
Copy link
Collaborator

Choose a reason for hiding this comment

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

first item in tuple goes to hadoop api
does it expect ?construct_parameters=X instead of ?applicationTypes=X in query string?

Copy link
Collaborator

@ediskandarov-cur ediskandarov-cur left a comment

Choose a reason for hiding this comment

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

👍 looks good to me
maybe except rename of application_types query string argument

@ediskandarov-cur
Copy link
Collaborator

ediskandarov-cur commented Sep 22, 2018

@kevin-bates your concern about http_conn is valid.
On the other hand I didn't have an intention to include it in contract. That property should have been private.

@kevin-bates
Copy link
Member

@toidi - thanks for the explanation - good to know there wasn't intention to make the property public. I was thinking about taking the version approach that @lresende suggested as well, and I think moving to 0.3.0 is probably the best approach since it covers our bases.

Copy link
Member

@kevin-bates kevin-bates left a comment

Choose a reason for hiding this comment

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

Based on the final discussion of http_conn, these changes look good to me. Thanks for handling this @lresende and @toidi for your input and guidance.

Integration test that, given a provided YARN ENDPOINT,
execute some real scenario test against that server.

Note that, if no YARN ENDPOINT is provided, the tests
are ignored.
@lresende lresende merged commit e017dcf into gateway-experiments:master Sep 22, 2018
@lresende lresende deleted the security branch September 22, 2018 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants