|
@@ -15,15 +15,28 @@
|
|
|
# See the License for the specific language governing permissions and
|
|
# See the License for the specific language governing permissions and
|
|
|
# limitations under the License.
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
|
|
+from desktop.lib.exceptions_renderable import PopupException
|
|
|
|
|
+from django.utils.translation import ugettext as _
|
|
|
|
|
+
|
|
|
|
|
+from kazoo.client import KazooClient
|
|
|
|
|
+
|
|
|
from libsentry.client import SentryClient
|
|
from libsentry.client import SentryClient
|
|
|
from libsentry.conf import HOSTNAME, PORT
|
|
from libsentry.conf import HOSTNAME, PORT
|
|
|
|
|
+from libsentry.sentry_site import get_sentry_server_ha_enabled, get_sentry_server_ha_has_security, get_sentry_server_ha_zookeeper_quorum, get_sentry_server_ha_zookeeper_namespace
|
|
|
|
|
|
|
|
import logging
|
|
import logging
|
|
|
|
|
+import json
|
|
|
|
|
+import threading
|
|
|
|
|
|
|
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+_api_cache = None
|
|
|
|
|
+_api_cache_lock = threading.Lock()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
class SentryException(Exception):
|
|
class SentryException(Exception):
|
|
|
def __init__(self, e):
|
|
def __init__(self, e):
|
|
|
super(SentryException, self).__init__(e)
|
|
super(SentryException, self).__init__(e)
|
|
@@ -34,8 +47,53 @@ class SentryException(Exception):
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_api(user):
|
|
def get_api(user):
|
|
|
|
|
+ if get_sentry_server_ha_enabled():
|
|
|
|
|
+ servers = _get_server_properties()
|
|
|
|
|
+ if servers:
|
|
|
|
|
+ server = servers[0]
|
|
|
|
|
+ else:
|
|
|
|
|
+ raise PopupException(_('No Sentry servers are available.'))
|
|
|
|
|
+ else:
|
|
|
|
|
+ server = {
|
|
|
|
|
+ 'hostname': HOSTNAME.get(),
|
|
|
|
|
+ 'port': PORT.get()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return SentryApi(SentryClient(HOSTNAME.get(), PORT.get(), user.username))
|
|
return SentryApi(SentryClient(HOSTNAME.get(), PORT.get(), user.username))
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+def _get_server_properties():
|
|
|
|
|
+ global _api_cache
|
|
|
|
|
+
|
|
|
|
|
+ if _api_cache is None:
|
|
|
|
|
+ _api_cache_lock.acquire()
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ if _api_cache is None:
|
|
|
|
|
+ zk = KazooClient(hosts=get_sentry_server_ha_zookeeper_quorum(), read_only=True)
|
|
|
|
|
+
|
|
|
|
|
+ if get_sentry_server_ha_has_security():
|
|
|
|
|
+ pass # zk.add_kerb
|
|
|
|
|
+
|
|
|
|
|
+ zk.start()
|
|
|
|
|
+
|
|
|
|
|
+ servers = []
|
|
|
|
|
+ namespace = get_sentry_server_ha_zookeeper_namespace()
|
|
|
|
|
+
|
|
|
|
|
+ children = zk.get_children("/%s/sentry-service/sentry-service/" % namespace)
|
|
|
|
|
+ for server in children:
|
|
|
|
|
+ data, stat = zk.get("/%s/sentry-service/sentry-service/%s" % (namespace, server))
|
|
|
|
|
+ server = json.loads(data.decode("utf-8"))
|
|
|
|
|
+ servers.append({'hostname': server['address'], 'port': server['sslPort'] if server['sslPort'] else server['port']})
|
|
|
|
|
+
|
|
|
|
|
+ zk.stop()
|
|
|
|
|
+
|
|
|
|
|
+ _api_cache = servers
|
|
|
|
|
+ finally:
|
|
|
|
|
+ _api_cache_lock.release()
|
|
|
|
|
+
|
|
|
|
|
+ return _api_cache
|
|
|
|
|
+
|
|
|
|
|
|
|
|
class SentryApi(object):
|
|
class SentryApi(object):
|
|
|
|
|
|