Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3625ecd
Add utility script for listing tooz / service registry groups and
Kami Feb 13, 2019
b95e7c8
Add support for registering a service in service registry inside
Kami Feb 13, 2019
eb56273
Fix lint and Python 3 compatibility.
Kami Feb 13, 2019
293757a
Make sure we register all the services in the service registry.
Kami Feb 13, 2019
079448c
Update config with sample configuration for coordination section.
Kami Feb 13, 2019
6d2d7d9
Update NoOpCoordinationBackend so it correctly works with group
Kami Feb 13, 2019
46d7f56
Fix lint.
Kami Feb 13, 2019
b7e618f
Fix scheduler test configs in unit tests
m4dcoder Feb 13, 2019
09ed1b5
Add a changelog entry.
Kami Feb 13, 2019
9e2fb82
Merge branch 'master' of github.com:StackStorm/st2 into service_registry
Kami Feb 14, 2019
4660d97
Add two new service registry related admin API endpoint.
Kami Feb 14, 2019
5141fc7
Refactor it in a separate function so it's more self contained and
Kami Feb 15, 2019
b4f1f13
Add test cases for new service registry related API endpoint.
Kami Feb 15, 2019
ed9b270
Add changelog entry.
Kami Feb 15, 2019
af231a0
Add new service registry endpoints to RBAC API endpoint test cases.
Kami Feb 15, 2019
cead842
Only tear down the coordination service.
Kami Feb 15, 2019
de605d8
Add RBAC test cases for the new service regstry API endpoints.
Kami Feb 15, 2019
76406ff
Re-generate openapi config.
Kami Feb 15, 2019
4963266
Update comment, fix lint.
Kami Feb 15, 2019
9f94334
Merge branch 'master' of github.com:StackStorm/st2 into service_registry
Kami Mar 3, 2019
57ad129
Always refer to the same coordinator instance.
Kami Mar 3, 2019
7fa0934
Use NoOp driver for tests since zake one causes some tests go hang.
Kami Mar 3, 2019
3aeb612
Merge branch 'master' of github.com:StackStorm/st2 into service_registry
Kami Mar 11, 2019
94ac8bb
Merge branch 'master' of github.com:StackStorm/st2 into service_registry
Kami Mar 11, 2019
aa862a2
Merge branch 'master' of github.com:StackStorm/st2 into service_registry
Kami Mar 11, 2019
fd63345
Remove extra whitespace.
Kami Mar 11, 2019
ed86153
Remove debug code.
Kami Mar 11, 2019
b0e48e2
Add new CLI commands for listing service registry groups and members:
Kami Mar 11, 2019
33a3ced
Update changelog.
Kami Mar 11, 2019
825778d
Update more affected tests.
Kami Mar 11, 2019
4208251
Don't use cached coordinator instances for tests.
Kami Mar 11, 2019
dd27733
Make sure we correctly tear down the coordinator.
Kami Mar 11, 2019
2c113b9
Fix Python 3 related test failures.
Kami Mar 11, 2019
32a4d46
Use full absolute paths in launchdev script.
Kami Mar 11, 2019
98b77d1
Make sure we also start coordinator heartbeat process in places where we
Kami Mar 11, 2019
f5f5116
Use more compatible function.
Kami Mar 11, 2019
f530cbe
Revert "Make sure we also start coordinator heartbeat process in plac…
Kami Mar 11, 2019
5ccf4ba
Update affected test.
Kami Mar 11, 2019
4ebcdc3
Update sample config.
Kami Mar 11, 2019
ed37c02
Revert "Revert "Make sure we also start coordinator heartbeat process…
Kami Mar 12, 2019
fc5150a
Merge branch 'master' of github.com:StackStorm/st2 into service_registry
Kami Mar 18, 2019
2f481e0
Fix typo.
Kami Mar 18, 2019
893cfcc
Add docstring which clarifies the behavior.
Kami Mar 18, 2019
e4cfa82
Only teardown coordinator if one has been initialized.
Kami Mar 18, 2019
639e708
Make sure we start heartbeat process everywhere we retrieve coordinator
Kami Mar 18, 2019
3c82ff4
To be on the safe side default start_heart to True and log a message
Kami Mar 18, 2019
5c6cc5d
Use consistent casing.
Kami Mar 18, 2019
100ad9f
Remove assignment.
Kami Mar 18, 2019
7fffa52
Use item variable name instead of group_id_.
Kami Mar 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ Added

For backward compatibility reasons, if pack metadata file doesn't contain that attribute, it's
assumed it only works with Python 2. (new feature) #4474
* Update service bootstrap code and make sure all the services register in a service registry once
they come online and become available.

This functionality is only used internally and will only work if configuration backend is
correctly configured in ``st2.conf`` (new feature) #4548
* Add new ``GET /v1/service_registry/groups`` and
``GET /v1/service_registry/groups/<group_id>/members`` API endpoint for listing available service
registry groups and members.

NOTE: This API endpoint is behind a RBAC control check and can only be views by the admins.
(new feature) #4548

Also add corresponding CLI commands - ``st2 service-registry group list``,
``st2 service registry member list [--group-id=<group id>]``

* Adding ``Cache-Control`` header to all API responses so clients will favor
refresh from API instead of using cached version.
Expand Down
11 changes: 11 additions & 0 deletions conf/st2.dev.conf
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ port = 514
facility = local7
protocol = udp

[coordination]
# NOTE: Service registry / groups functionality is only available in the following drivers:
# - zookeeper
# - redis
# - etcd3
# - etcd3gw
# Keep in mind that zake driver works in process so it won't work when testing cross process
# / cross server functionality
#url = redis://localhost
#url = kazoo://localhost

[webui]
# webui_base_url = https://mywebhost.domain

Expand Down
7 changes: 6 additions & 1 deletion st2actions/st2actions/cmd/actionrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ def sigterm_handler(signum=None, frame=None):


def _setup():
capabilities = {
'name': 'actionrunner',
'type': 'passive'
}
common_setup(service='actionrunner', config=config, setup_db=True, register_mq_exchanges=True,
register_signal_handlers=True)
register_signal_handlers=True, service_registry=True, capabilities=capabilities)

_setup_sigterm_handler()


Expand Down
7 changes: 6 additions & 1 deletion st2actions/st2actions/cmd/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ def sigterm_handler(signum=None, frame=None):


def _setup():
capabilities = {
'name': 'scheduler',
'type': 'passive'
}
common_setup(service='scheduler', config=config, setup_db=True, register_mq_exchanges=True,
register_signal_handlers=True)
register_signal_handlers=True, service_registry=True, capabilities=capabilities)

_setup_sigterm_handler()


Expand Down
6 changes: 5 additions & 1 deletion st2actions/st2actions/cmd/st2notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@


def _setup():
capabilities = {
'name': 'notifier',
'type': 'passive'
}
common_setup(service='notifier', config=config, setup_db=True, register_mq_exchanges=True,
register_signal_handlers=True)
register_signal_handlers=True, service_registry=True, capabilities=capabilities)


def _run_worker():
Expand Down
8 changes: 6 additions & 2 deletions st2actions/st2actions/cmd/st2resultstracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@


def _setup():
common_setup(service='resultstracker', config=config, setup_db=True,
register_mq_exchanges=True, register_signal_handlers=True)
capabilities = {
'name': 'resultstracker',
'type': 'passive'
}
common_setup(service='resultstracker', config=config, setup_db=True, register_mq_exchanges=True,
register_signal_handlers=True, service_registry=True, capabilities=capabilities)


def _run_worker():
Expand Down
8 changes: 7 additions & 1 deletion st2actions/st2actions/cmd/workflow_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,18 @@ def sigterm_handler(signum=None, frame=None):


def setup():
capabilities = {
'name': 'workflowengine',
'type': 'passive'
}
common_setup(
service='workflow_engine',
config=config,
setup_db=True,
register_mq_exchanges=True,
register_signal_handlers=True
register_signal_handlers=True,
service_registry=True,
capabilities=capabilities
)

setup_sigterm_handler()
Expand Down
2 changes: 1 addition & 1 deletion st2actions/st2actions/scheduler/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def __init__(self):
self.message_type = LiveActionDB
self._shutdown = False
self._pool = eventlet.GreenPool(size=cfg.CONF.scheduler.pool_size)
self._coordinator = coordination_service.get_coordinator()
self._coordinator = coordination_service.get_coordinator(start_heart=True)
self._main_thread = None
self._cleanup_thread = None

Expand Down
1 change: 1 addition & 0 deletions st2actions/tests/unit/policies/test_concurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
# Reset the coordinator.
coordination.coordinator_teardown(coordination.COORDINATOR)
coordination.COORDINATOR = None

super(ConcurrencyPolicyTestCase, cls).tearDownClass()
Expand Down
1 change: 1 addition & 0 deletions st2actions/tests/unit/policies/test_concurrency_by_attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
# Reset the coordinator.
coordination.coordinator_teardown(coordination.COORDINATOR)
coordination.COORDINATOR = None

super(ConcurrencyByAttributePolicyTestCase, cls).tearDownClass()
Expand Down
9 changes: 9 additions & 0 deletions st2api/st2api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ def setup_app(config={}):
monkey_patch()

st2api_config.register_opts()
capabilities = {
'name': 'api',
'listen_host': cfg.CONF.api.host,
'listen_port': cfg.CONF.api.port,
'type': 'active'
}

# This should be called in gunicorn case because we only want
# workers to connect to db, rabbbitmq etc. In standalone HTTP
# server case, this setup would have already occurred.
Expand All @@ -54,6 +61,8 @@ def setup_app(config={}):
register_signal_handlers=True,
register_internal_trigger_types=True,
run_migrations=True,
service_registry=True,
capabilities=capabilities,
config_args=config.get('config_args', None))

# Additional pre-run time checks
Expand Down
10 changes: 9 additions & 1 deletion st2api/st2api/cmd/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,16 @@


def _setup():
capabilities = {
'name': 'api',
'listen_host': cfg.CONF.api.host,
'listen_port': cfg.CONF.api.port,
'type': 'active'
}

common_setup(service='api', config=config, setup_db=True, register_mq_exchanges=True,
register_signal_handlers=True, register_internal_trigger_types=True)
register_signal_handlers=True, register_internal_trigger_types=True,
service_registry=True, capabilities=capabilities)

# Additional pre-run time checks
validate_rbac_is_correctly_configured()
Expand Down
77 changes: 77 additions & 0 deletions st2api/st2api/controllers/v1/service_registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import six

from tooz.coordination import GroupNotCreated

from st2common.services import coordination
from st2common.exceptions.db import StackStormDBObjectNotFoundError
from st2common.rbac import utils as rbac_utils

__all__ = [
'ServiceRegistryGroupsController',
'ServiceRegistryGroupMembersController',
]


class ServiceRegistryGroupsController(object):
def get_all(self, requester_user):
rbac_utils.assert_user_is_admin(user_db=requester_user)

coordinator = coordination.get_coordinator()

group_ids = list(coordinator.get_groups().get())
group_ids = [item.decode('utf-8') for item in group_ids]

result = {
'groups': group_ids
}
return result


class ServiceRegistryGroupMembersController(object):
def get_one(self, group_id, requester_user):
rbac_utils.assert_user_is_admin(user_db=requester_user)

coordinator = coordination.get_coordinator()

if not isinstance(group_id, six.binary_type):
group_id = group_id.encode('utf-8')

try:
member_ids = list(coordinator.get_members(group_id).get())
except GroupNotCreated:
msg = ('Group with ID "%s" not found.' % (group_id.decode('utf-8')))
raise StackStormDBObjectNotFoundError(msg)

result = {
'members': []
}

for member_id in member_ids:
capabilities = coordinator.get_member_capabilities(group_id, member_id).get()
item = {
'group_id': group_id.decode('utf-8'),
'member_id': member_id.decode('utf-8'),
'capabilities': capabilities
}
result['members'].append(item)

return result


groups_controller = ServiceRegistryGroupsController()
members_controller = ServiceRegistryGroupMembersController()
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
from st2api.controllers.v1.webhooks import HooksHolder
from st2common.persistence.rbac import UserRoleAssignment
from st2common.models.db.rbac import UserRoleAssignmentDB
from st2common.service_setup import register_service_in_service_registry
from st2common.services import coordination

from st2tests import config as tests_config
from st2tests.fixturesloader import FixturesLoader

from tests.base import APIControllerWithRBACTestCase
from tests.unit.controllers.v1.test_webhooks import DUMMY_TRIGGER_DICT

Expand Down Expand Up @@ -110,6 +114,29 @@ class APIControllersRBACTestCase(APIControllerWithRBACTestCase):
register_packs = True
fixtures_loader = FixturesLoader()

coordinator = None

@classmethod
def setUpClass(cls):
tests_config.parse_args(coordinator_noop=True)

super(APIControllersRBACTestCase, cls).setUpClass()

cls.coordinator = coordination.get_coordinator(use_cache=False)

# Register mock service in the service registry for testing purposes
service = six.binary_type(six.text_type('mock_service').encode('ascii'))
register_service_in_service_registry(service=service,
capabilities={'key1': 'value1',
'name': 'mock_service'},
start_heart=True)

@classmethod
def tearDownClass(cls):
super(APIControllersRBACTestCase, cls).tearDownClass()

coordination.coordinator_teardown(cls.coordinator)

def setUp(self):
super(APIControllersRBACTestCase, self).setUp()

Expand Down Expand Up @@ -450,6 +477,17 @@ def test_api_endpoints_behind_rbac_wall(self):
'path': '/v1/rules/views',
'method': 'GET',
'is_getall': True
},
# Service registry
{
'path': '/v1/service_registry/groups',
'method': 'GET',
'is_getall': True
},
{
'path': '/v1/service_registry/groups/mock_service/members',
'method': 'GET',
'is_getall': True
}
]

Expand Down
Loading