%PDF- %PDF-
Direktori : /usr/lib/python2.7/site-packages/salt/states/ |
Current File : //usr/lib/python2.7/site-packages/salt/states/glassfish.py |
# -*- coding: utf-8 -*- ''' Manage Glassfish/Payara server .. versionadded:: Carbon Management of glassfish using it's RESTful API You can setup connection parameters like this .. code-block:: yaml - server: - ssl: true - url: localhost - port: 4848 - user: admin - password: changeit ''' from __future__ import absolute_import, print_function, unicode_literals try: import salt.utils.json from salt.ext import six from salt.exceptions import CommandExecutionError import requests HAS_LIBS = True except ImportError: HAS_LIBS = False def __virtual__(): ''' Only load if glassfish module is available ''' return 'glassfish.enum_connector_c_pool' in __salt__ and HAS_LIBS def _json_to_unicode(data): ''' Encode json values in unicode to match that of the API ''' ret = {} for key, value in data.items(): if not isinstance(value, six.text_type): if isinstance(value, dict): ret[key] = _json_to_unicode(value) else: ret[key] = six.text_type(value).lower() else: ret[key] = value return ret def _is_updated(old_conf, new_conf): ''' Compare the API results to the current statefile data ''' changed = {} # Dirty json hacking to get parameters in the same format new_conf = _json_to_unicode(salt.utils.json.loads( salt.utils.json.dumps(new_conf, ensure_ascii=False))) old_conf = salt.utils.json.loads(salt.utils.json.dumps(old_conf, ensure_ascii=False)) for key, value in old_conf.items(): oldval = six.text_type(value).lower() if key in new_conf: newval = six.text_type(new_conf[key]).lower() if oldval == 'null' or oldval == 'none': oldval = '' if key in new_conf and newval != oldval: changed[key] = {'old': oldval, 'new': newval} return changed def _do_element_present(name, elem_type, data, server=None): ''' Generic function to create or update an element ''' ret = {'changes': {}, 'update': False, 'create': False, 'error': None} try: elements = __salt__['glassfish.enum_{0}'.format(elem_type)]() except requests.ConnectionError as error: if __opts__['test']: ret['changes'] = {'Name': name, 'Params': data} ret['create'] = True return ret else: ret['error'] = "Can't connect to the server" return ret if not elements or name not in elements: ret['changes'] = {'Name': name, 'Params': data} ret['create'] = True if not __opts__['test']: try: __salt__['glassfish.create_{0}'.format(elem_type)](name, server=server, **data) except CommandExecutionError as error: ret['error'] = error return ret elif elements and any(data): current_data = __salt__['glassfish.get_{0}'.format(elem_type)](name, server=server) data_diff = _is_updated(current_data, data) if data_diff: ret['update'] = True ret['changes'] = data_diff if not __opts__['test']: try: __salt__['glassfish.update_{0}'.format(elem_type)](name, server=server, **data) except CommandExecutionError as error: ret['error'] = error return ret def _do_element_absent(name, elem_type, data, server=None): ''' Generic function to delete an element ''' ret = {'delete': False, 'error': None} try: elements = __salt__['glassfish.enum_{0}'.format(elem_type)]() except requests.ConnectionError as error: if __opts__['test']: ret['create'] = True return ret else: ret['error'] = "Can't connect to the server" return ret if elements and name in elements: ret['delete'] = True if not __opts__['test']: try: __salt__['glassfish.delete_{0}'.format(elem_type)](name, server=server, **data) except CommandExecutionError as error: ret['error'] = error return ret def connection_factory_present(name, restype='connection_factory', description='', enabled=True, min_size=1, max_size=250, resize_quantity=2, idle_timeout=300, wait_timeout=60, reconnect_on_failure=False, transaction_support='', connection_validation=False, server=None): ''' Ensures that the Connection Factory is present name Name of the connection factory restype Type of the connection factory, can be either ``connection_factory``, ``queue_connection_factory` or ``topic_connection_factory``, defaults to ``connection_factory`` description Description of the connection factory enabled Is the connection factory enabled? defaults to ``true`` min_size Minimum and initial number of connections in the pool, defaults to ``1`` max_size Maximum number of connections that can be created in the pool, defaults to ``250`` resize_quantity Number of connections to be removed when idle_timeout expires, defaults to ``2`` idle_timeout Maximum time a connection can remain idle in the pool, in seconds, defaults to ``300`` wait_timeout Maximum time a caller can wait before timeout, in seconds, defaults to ``60`` reconnect_on_failure Close all connections and reconnect on failure (or reconnect only when used), defaults to ``false`` transaction_support Level of transaction support, can be either ``XATransaction``, ``LocalTransaction`` or ``NoTransaction`` connection_validation Connection validation is required, defaults to ``false`` ''' ret = {'name': name, 'result': None, 'comment': None, 'changes': {}} # Manage parameters pool_data = {} res_data = {} pool_name = '{0}-Connection-Pool'.format(name) if restype == 'topic_connection_factory': pool_data['connectionDefinitionName'] = 'javax.jms.TopicConnectionFactory' elif restype == 'queue_connection_factory': pool_data['connectionDefinitionName'] = 'javax.jms.QueueConnectionFactory' elif restype == 'connection_factory': pool_data['connectionDefinitionName'] = 'javax.jms.ConnectionFactory' else: ret['result'] = False ret['comment'] = 'Invalid restype' return ret pool_data['description'] = description res_data['description'] = description res_data['enabled'] = enabled res_data['poolName'] = pool_name pool_data['steadyPoolSize'] = min_size pool_data['maxPoolSize'] = max_size pool_data['poolResizeQuantity'] = resize_quantity pool_data['idleTimeoutInSeconds'] = idle_timeout pool_data['maxWaitTimeInMillis'] = wait_timeout*1000 pool_data['failAllConnections'] = reconnect_on_failure if transaction_support: if transaction_support == 'xa_transaction': pool_data['transactionSupport'] = 'XATransaction' elif transaction_support == 'local_transaction': pool_data['transactionSupport'] = 'LocalTransaction' elif transaction_support == 'no_transaction': pool_data['transactionSupport'] = 'NoTransaction' else: ret['result'] = False ret['comment'] = 'Invalid transaction_support' return ret pool_data['isConnectionValidationRequired'] = connection_validation pool_ret = _do_element_present(pool_name, 'connector_c_pool', pool_data, server) res_ret = _do_element_present(name, 'connector_resource', res_data, server) if not pool_ret['error'] and not res_ret['error']: if not __opts__['test']: ret['result'] = True if pool_ret['create'] or res_ret['create']: ret['changes']['pool'] = pool_ret['changes'] ret['changes']['resource'] = res_ret['changes'] if __opts__['test']: ret['comment'] = 'Connection factory set to be created' else: ret['comment'] = 'Connection factory created' elif pool_ret['update'] or res_ret['update']: ret['changes']['pool'] = pool_ret['changes'] ret['changes']['resource'] = res_ret['changes'] if __opts__['test']: ret['comment'] = 'Connection factory set to be updated' else: ret['comment'] = 'Connection factory updated' else: ret['result'] = True ret['changes'] = {} ret['comment'] = 'Connection factory is already up-to-date' else: ret['result'] = False ret['comment'] = 'ERROR: {0} // {1}'.format(pool_ret['error'], res_ret['error']) return ret def connection_factory_absent(name, both=True, server=None): ''' Ensures the transaction factory is absent. name Name of the connection factory both Delete both the pool and the resource, defaults to ``true`` ''' ret = {'name': name, 'result': None, 'comment': None, 'changes': {}} pool_name = '{0}-Connection-Pool'.format(name) pool_ret = _do_element_absent(pool_name, 'connector_c_pool', {'cascade': both}, server) if not pool_ret['error']: if __opts__['test'] and pool_ret['delete']: ret['comment'] = 'Connection Factory set to be deleted' elif pool_ret['delete']: ret['result'] = True ret['comment'] = 'Connection Factory deleted' else: ret['result'] = True ret['comment'] = 'Connection Factory doesn\'t exist' else: ret['result'] = False ret['comment'] = 'Error: {0}'.format(pool_ret['error']) return ret def destination_present(name, physical, restype='queue', description='', enabled=True, server=None): ''' Ensures that the JMS Destination Resource (queue or topic) is present name The JMS Queue/Topic name physical The Physical destination name restype The JMS Destination resource type, either ``queue`` or ``topic``, defaults is ``queue`` description A description of the resource enabled Defaults to ``True`` ''' ret = {'name': name, 'result': None, 'comment': None, 'changes': {}} params = {} # Set parameters dict if restype == 'queue': params['resType'] = 'javax.jms.Queue' params['className'] = 'com.sun.messaging.Queue' elif restype == 'topic': params['resType'] = 'javax.jms.Topic' params['className'] = 'com.sun.messaging.Topic' else: ret['result'] = False ret['comment'] = 'Invalid restype' return ret params['properties'] = {'Name': physical} params['description'] = description params['enabled'] = enabled jms_ret = _do_element_present(name, 'admin_object_resource', params, server) if not jms_ret['error']: if not __opts__['test']: ret['result'] = True if jms_ret['create'] and __opts__['test']: ret['comment'] = 'JMS Queue set to be created' elif jms_ret['create']: ret['changes'] = jms_ret['changes'] ret['comment'] = 'JMS queue created' elif jms_ret['update'] and __opts__['test']: ret['comment'] = 'JMS Queue set to be updated' elif jms_ret['update']: ret['changes'] = jms_ret['changes'] ret['comment'] = 'JMS Queue updated' else: ret['result'] = True ret['comment'] = 'JMS Queue already up-to-date' else: ret['result'] = False ret['comment'] = 'Error from API: {0}'.format(jms_ret['error']) return ret def destination_absent(name, server=None): ''' Ensures that the JMS Destination doesn't exists name Name of the JMS Destination ''' ret = {'name': name, 'result': None, 'comment': None, 'changes': {}} jms_ret = _do_element_absent(name, 'admin_object_resource', {}, server) if not jms_ret['error']: if __opts__['test'] and jms_ret['delete']: ret['comment'] = 'JMS Queue set to be deleted' elif jms_ret['delete']: ret['result'] = True ret['comment'] = 'JMS Queue deleted' else: ret['result'] = True ret['comment'] = 'JMS Queue doesn\'t exist' else: ret['result'] = False ret['comment'] = 'Error: {0}'.format(jms_ret['error']) return ret def jdbc_datasource_present(name, description='', enabled=True, restype='datasource', vendor='mysql', sql_url='', sql_user='', sql_password='', min_size=8, max_size=32, resize_quantity=2, idle_timeout=300, wait_timeout=60, non_transactional=False, transaction_isolation='', isolation_guaranteed=True, server=None): ''' Ensures that the JDBC Datasource exists name Name of the datasource description Description of the datasource enabled Is the datasource enabled? defaults to ``true`` restype Resource type, can be ``datasource``, ``xa_datasource``, ``connection_pool_datasource`` or ``driver``, defaults to ``datasource`` vendor SQL Server type, currently supports ``mysql``, ``postgresql`` and ``mssql``, defaults to ``mysql`` sql_url URL of the server in jdbc form sql_user Username for the server sql_password Password for that username min_size Minimum and initial number of connections in the pool, defaults to ``8`` max_size Maximum number of connections that can be created in the pool, defaults to ``32`` resize_quantity Number of connections to be removed when idle_timeout expires, defaults to ``2`` idle_timeout Maximum time a connection can remain idle in the pool, in seconds, defaults to ``300`` wait_timeout Maximum time a caller can wait before timeout, in seconds, defaults to ``60`` non_transactional Return non-transactional connections transaction_isolation Defaults to the JDBC driver default isolation_guaranteed All connections use the same isolation level ''' ret = {'name': name, 'result': None, 'comment': None, 'changes': {}} # Manage parameters res_name = 'jdbc/{0}'.format(name) pool_data = {} pool_data_properties = {} res_data = {} if restype == 'datasource': pool_data['resType'] = 'javax.sql.DataSource' elif restype == 'xa_datasource': pool_data['resType'] = 'javax.sql.XADataSource' elif restype == 'connection_pool_datasource': pool_data['resType'] = 'javax.sql.ConnectionPoolDataSource' elif restype == 'driver': pool_data['resType'] = 'javax.sql.Driver' datasources = {} datasources['mysql'] = { 'driver': 'com.mysql.jdbc.Driver', 'datasource': 'com.mysql.jdbc.jdbc2.optional.MysqlDataSource', 'xa_datasource': 'com.mysql.jdbc.jdbc2.optional.MysqlXADataSource', 'connection_pool_datasource': 'com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource' } datasources['postgresql'] = { 'driver': 'org.postgresql.Driver', 'datasource': 'org.postgresql.ds.PGSimpleDataSource', 'xa_datasource': 'org.postgresql.xa.PGXADataSource', 'connection_pool_datasource': 'org.postgresql.ds.PGConnectionPoolDataSource' } datasources['mssql'] = { 'driver': 'com.microsoft.sqlserver.jdbc.SQLServerDriver', 'datasource': 'com.microsoft.sqlserver.jdbc.SQLServerDataSource', 'xa_datasource': 'com.microsoft.sqlserver.jdbc.SQLServerXADataSource', 'connection_pool_datasource': 'com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource' } if restype == 'driver': pool_data['driverClassname'] = datasources[vendor]['driver'] else: pool_data['datasourceClassname'] = datasources[vendor][restype] pool_data_properties['url'] = sql_url pool_data_properties['user'] = sql_user pool_data_properties['password'] = sql_password pool_data['properties'] = pool_data_properties pool_data['description'] = description res_data['description'] = description res_data['poolName'] = name res_data['enabled'] = enabled pool_data['steadyPoolSize'] = min_size pool_data['maxPoolSize'] = max_size pool_data['poolResizeQuantity'] = resize_quantity pool_data['idleTimeoutInSeconds'] = idle_timeout pool_data['maxWaitTimeInMillis'] = wait_timeout*1000 pool_data['nonTransactionalConnections'] = non_transactional pool_data['transactionIsolationLevel'] = transaction_isolation pool_data['isIsolationLevelGuaranteed'] = isolation_guaranteed pool_ret = _do_element_present(name, 'jdbc_connection_pool', pool_data, server) res_ret = _do_element_present(res_name, 'jdbc_resource', res_data, server) if not pool_ret['error'] and not res_ret['error']: if not __opts__['test']: ret['result'] = True if pool_ret['create'] or res_ret['create']: ret['changes']['pool'] = pool_ret['changes'] ret['changes']['resource'] = res_ret['changes'] if __opts__['test']: ret['comment'] = 'JDBC Datasource set to be created' else: ret['comment'] = 'JDBC Datasource created' elif pool_ret['update'] or res_ret['update']: ret['changes']['pool'] = pool_ret['changes'] ret['changes']['resource'] = res_ret['changes'] if __opts__['test']: ret['comment'] = 'JDBC Datasource set to be updated' else: ret['comment'] = 'JDBC Datasource updated' else: ret['result'] = True ret['changes'] = {} ret['comment'] = 'JDBC Datasource is already up-to-date' else: ret['result'] = False ret['comment'] = 'ERROR: {0} // {1}'.format(pool_ret['error'], res_ret['error']) return ret def jdbc_datasource_absent(name, both=True, server=None): ''' Ensures the JDBC Datasource doesn't exists name Name of the datasource both Delete both the pool and the resource, defaults to ``true`` ''' ret = {'name': name, 'result': None, 'comment': None, 'changes': {}} pool_ret = _do_element_absent(name, 'jdbc_connection_pool', {'cascade': both}, server) if not pool_ret['error']: if __opts__['test'] and pool_ret['delete']: ret['comment'] = 'JDBC Datasource set to be deleted' elif pool_ret['delete']: ret['result'] = True ret['comment'] = 'JDBC Datasource deleted' else: ret['result'] = True ret['comment'] = 'JDBC Datasource doesn\'t exist' else: ret['result'] = False ret['comment'] = 'Error: {0}'.format(pool_ret['error']) return ret def system_properties_present(server=None, **kwargs): ''' Ensures that the system properties are present properties The system properties ''' ret = {'name': '', 'result': None, 'comment': None, 'changes': {}} del kwargs['name'] try: data = __salt__['glassfish.get_system_properties'](server=server) except requests.ConnectionError as error: if __opts__['test']: ret['changes'] = kwargs ret['result'] = None return ret else: ret['error'] = "Can't connect to the server" return ret ret['changes'] = {'data': data, 'kwargs': kwargs} if not data == kwargs: data.update(kwargs) if not __opts__['test']: try: __salt__['glassfish.update_system_properties'](data, server=server) ret['changes'] = kwargs ret['result'] = True ret['comment'] = 'System properties updated' except CommandExecutionError as error: ret['comment'] = error ret['result'] = False else: ret['result'] = None ret['changes'] = kwargs ret['coment'] = 'System properties would have been updated' else: ret['changes'] = {} ret['result'] = True ret['comment'] = 'System properties are already up-to-date' return ret def system_properties_absent(name, server=None): ''' Ensures that the system property doesn't exists name Name of the system property ''' ret = {'name': '', 'result': None, 'comment': None, 'changes': {}} try: data = __salt__['glassfish.get_system_properties'](server=server) except requests.ConnectionError as error: if __opts__['test']: ret['changes'] = {'Name': name} ret['result'] = None return ret else: ret['error'] = "Can't connect to the server" return ret if name in data: if not __opts__['test']: try: __salt__['glassfish.delete_system_properties'](name, server=server) ret['result'] = True ret['comment'] = 'System properties deleted' except CommandExecutionError as error: ret['comment'] = error ret['result'] = False else: ret['result'] = None ret['comment'] = 'System properties would have been deleted' ret['changes'] = {'Name': name} else: ret['result'] = True ret['comment'] = 'System properties are already absent' return ret