Esempio n. 1
0
 def _append_allow_curve_key(self, publickey):
     entry = AuthEntry(credentials=publickey)
     authfile = AuthFile(self.volttron_home + "/auth.json")
     try:
         authfile.add(entry)
     except AuthFileEntryAlreadyExists:
         pass
Esempio n. 2
0
    def _allow(self, environ, start_response, data=None):
        _log.info('Allowing new vc instance to connect to server.')
        jsondata = jsonapi.loads(data)
        json_validate_request(jsondata)

        assert jsondata.get('method') == 'allowvc'
        assert jsondata.get('params')

        params = jsondata.get('params')
        if isinstance(params, list):
            vcpublickey = params[0]
        else:
            vcpublickey = params.get('vcpublickey')

        assert vcpublickey
        assert len(vcpublickey) == 43

        authfile = AuthFile()
        authentry = AuthEntry(credentials=vcpublickey)

        try:
            authfile.add(authentry)
        except AuthFileEntryAlreadyExists:
            pass

        start_response('200 OK', [('Content-Type', 'application/json')])
        return jsonapi.dumps(json_result(jsondata['id'], "Added"))
Esempio n. 3
0
    def build_connection(self, peer=None, address=None, identity=None,
                         publickey=None, secretkey=None, serverkey=None,
                         capabilities=[], **kwargs):
        self.logit('Building connection to {}'.format(peer))
        self.allow_all_connections()

        if address is None:
            self.logit(
                'Default address was None so setting to current instances')
            address = self.vip_address
            serverkey = self.serverkey
        if serverkey is None:
            self.logit("serverkey wasn't set but the address was.")
            raise Exception("Invalid state.")

        if publickey is None or secretkey is None:
            self.logit('generating new public secret key pair')
            keyfile = tempfile.mktemp(".keys", "agent", self.volttron_home)
            keys = KeyStore(keyfile)
            keys.generate()
            publickey = keys.public
            secretkey = keys.secret
            entry = AuthEntry(capabilities=capabilities,
                              comments="Added by test",
                              credentials=keys.public)
            file = AuthFile(self.volttron_home + "/auth.json")
            file.add(entry)

        conn = Connection(address=address, peer=peer, publickey=publickey,
                          secretkey=secretkey, serverkey=serverkey,
                          volttron_home=self.volttron_home)

        return conn
Esempio n. 4
0
    def build_connection(self, peer=None, address=None, identity=None,
                         publickey=None, secretkey=None, serverkey=None,
                         capabilities=[], **kwargs):
        self.logit('Building connection to {}'.format(peer))
        self.allow_all_connections()

        if address is None:
            self.logit(
                'Default address was None so setting to current instances')
            address = self.vip_address
            serverkey = self.serverkey
        if serverkey is None:
            self.logit("serverkey wasn't set but the address was.")
            raise Exception("Invalid state.")

        if publickey is None or secretkey is None:
            self.logit('generating new public secret key pair')
            keyfile = tempfile.mktemp(".keys", "agent", self.volttron_home)
            keys = KeyStore(keyfile)
            keys.generate()
            publickey = keys.public
            secretkey = keys.secret
            entry = AuthEntry(capabilities=capabilities,
                              comments="Added by test",
                              credentials=keys.public)
            file = AuthFile(self.volttron_home + "/auth.json")
            file.add(entry)

        conn = Connection(address=address, peer=peer, publickey=publickey,
                          secretkey=secretkey, serverkey=serverkey,
                          volttron_home=self.volttron_home)

        return conn
def forwarder(request, volttron_instances):
    #print "Fixture forwarder"
    global volttron_instance1, volttron_instance2

    global forwarder_uuid, forwarder_config
    # 1. Update destination address in forwarder configuration

    if volttron_instance1.encrypt:
        tf = tempfile.NamedTemporaryFile()
        ks = KeyStore(tf.name)
        # generate public private key pair for instance1
        ks.generate()

        # add public key of instance1 to instance2 auth file
        authfile = AuthFile(volttron_instance2.volttron_home + "/auth.json")
        entry = AuthEntry(credentials=ks.public)
        authfile.add(entry)

        # setup destination address to include keys
        forwarder_config["destination-vip"] =\
            "{}?serverkey={}&publickey={}&secretkey={}".format(
                volttron_instance2.vip_address,
                volttron_instance2.serverkey,
                ks.public, ks.secret)
    else:
        forwarder_config["destination-vip"] = volttron_instance2.vip_address
    # 1: Install historian agent
    # Install and start sqlhistorian agent in instance2
    forwarder_uuid = volttron_instance1.install_agent(
        agent_dir="services/core/ForwardHistorian",
        config_file=forwarder_config,
        start=True)
    print("forwarder agent id: ", forwarder_uuid)
def forwarder(request, volttron_instances):
    #print "Fixture forwarder"
    global volttron_instance1, volttron_instance2

    global forwarder_uuid, forwarder_config
    # 1. Update destination address in forwarder configuration

    if volttron_instance1.encrypt:
        tf = tempfile.NamedTemporaryFile()
        ks = KeyStore(tf.name)
        # generate public private key pair for instance1
        ks.generate()

        # add public key of instance1 to instance2 auth file
        authfile = AuthFile(volttron_instance2.volttron_home + "/auth.json")
        entry = AuthEntry(credentials=ks.public())
        authfile.add(entry)

        # setup destination address to include keys
        forwarder_config["destination-vip"] =\
            "{}?serverkey={}&publickey={}&secretkey={}".format(
                volttron_instance2.vip_address,
                volttron_instance2.serverkey,
                ks.public(), ks.secret())
    else:
        forwarder_config["destination-vip"] = volttron_instance2.vip_address
    # 1: Install historian agent
    # Install and start sqlhistorian agent in instance2
    forwarder_uuid = volttron_instance1.install_agent(
        agent_dir="services/core/ForwardHistorian",
        config_file=forwarder_config,
        start=True)
    print("forwarder agent id: ", forwarder_uuid)
Esempio n. 7
0
 def _append_allow_curve_key(self, publickey):
     entry = AuthEntry(credentials=publickey)
     authfile = AuthFile(self.volttron_home + "/auth.json")
     try:
         authfile.add(entry)
     except AuthFileEntryAlreadyExists:
         pass
Esempio n. 8
0
 def allow_all_connections(self):
     """ Add a /.*/ entry to the auth.json file.
     """
     entry = AuthEntry(credentials="/.*/")
     authfile = AuthFile(self.volttron_home + "/auth.json")
     try:
         authfile.add(entry)
     except AuthFileEntryAlreadyExists:
         pass
Esempio n. 9
0
 def allow_all_connections(self):
     """ Add a /.*/ entry to the auth.json file.
     """
     entry = AuthEntry(credentials="/.*/")
     authfile = AuthFile(self.volttron_home + "/auth.json")
     try:
         authfile.add(entry)
     except AuthFileEntryAlreadyExists:
         pass
Esempio n. 10
0
    def manage(self, address, vcserverkey=None, vcpublickey=None):
        """ Allows the `VolttronCentralPlatform` to be managed.

        From the web perspective this should be after the user has specified
        that a user has blessed an agent to be able to be managed.

        When the user enters a discovery address in `VolttronCentral` it is
        implied that the user wants to manage a platform.

        :returns publickey of the `VolttronCentralPlatform`
        """
        _log.info('Manage request from address: {} serverkey: {}'.format(
            address, vcserverkey))

        self._was_unmanaged = False

        parsed = urlparse.urlparse(address)
        same_address = False
        if parsed.scheme == 'ipc':
            if self._volttron_central_ipc_address == address:
                same_address = True
            self._volttron_central_ipc_address = address
        elif parsed.scheme == 'tcp':
            _log.debug('Found tcp scheme adding AuthEntry')
            if self._volttron_central_tcp_address == address:
                same_address = True
            self._volttron_central_tcp_address = address
            self._volttron_central_serverkey = vcserverkey

            # Add the vcpublickey to the auth file.
            entry = AuthEntry(
                credentials=vcpublickey,
                capabilities=['manager'])  # , address=parsedaddress.hostname)
            authfile = AuthFile()
            authfile.add(entry)

        else:
            raise AttributeError('Invalid scheme in address')

        if self._vc_connection() is not None:
            self._is_registered = True
            self._is_registering = False
            _log.debug("Returning publickey from manage function.")
            return self.core.publickey

        raise NotManagedError(
            "Could not connect to specified volttron central")
Esempio n. 11
0
    def _enable_setup_mode(self, session_user, params):
        id = params.pop('message_id')
        if 'admin' not in session_user['groups']:
            _log.debug('Returning json_error enable_setup_mode')
            return jsonrpc.json_error(
                id, UNAUTHORIZED,
                "Admin access is required to enable setup mode")
        auth_file = AuthFile()
        entries = auth_file.find_by_credentials(".*")
        if len(entries) > 0:
            return "SUCCESS"

        entry = AuthEntry(credentials="/.*/",
                          comments="Un-Authenticated connections allowed here",
                          user_id="unknown")
        auth_file.add(entry)
        return "SUCCESS"
Esempio n. 12
0
    def _enable_setup_mode(self, session_user, params):
        id = params.pop('message_id')
        if 'admin' not in session_user['groups']:
            _log.debug('Returning json_error enable_setup_mode')
            return jsonrpc.json_error(
                id, UNAUTHORIZED,
                "Admin access is required to enable setup mode")
        auth_file = AuthFile()
        entries = auth_file.find_by_credentials(".*")
        if len(entries) > 0:
            return "SUCCESS"

        entry = AuthEntry(credentials="/.*/",
                          comments="Un-Authenticated connections allowed here",
                          user_id="unknown")
        auth_file.add(entry)
        return "SUCCESS"
Esempio n. 13
0
    def manage(self, address, vcserverkey, vcpublickey):
        """ Allows the `VolttronCentralPlatform` to be managed.

        From the web perspective this should be after the user has specified
        that a user has blessed an agent to be able to be managed.

        When the user enters a discovery address in `VolttronCentral` it is
        implied that the user wants to manage a platform.

        :returns publickey of the `VolttronCentralPlatform`
        """
        _log.info('Manage request from address: {} serverkey: {}'.format(
            address, vcserverkey))

        if self._managed:
            raise AlreadyManagedError()

        parsedaddress = urlparse.urlparse(address)

        if 'ipc://' == address[:6].lower():
            self._agent_connected_to_vc = self
        else:
            # Attempt to connect to the passed address and serverkey.
            self._agent_connected_to_vc = build_agent(
                address=address,
                serverkey=vcserverkey,
                publickey=self.core.publickey,
                secretkey=self.core.secretkey)

        version, peer, identity = self._agent_connected_to_vc.vip.hello().get(
            timeout=30)

        if not self == self._agent_connected_to_vc:
            # Add the vcpublickey to the auth file.
            entry = AuthEntry(
                credentials="CURVE:{}".format(vcpublickey),
                capabilities=['manager'])  # , address=parsedaddress.hostname)
            authfile = AuthFile()
            authfile.add(entry)
        self._managed = True
        self.core.spawn_later(2, self._publish_agent_list_to_vc)
        self.core.spawn_later(2, self._publish_stats)
        return self.core.publickey
Esempio n. 14
0
    def manage(self, address, vcserverkey, vcpublickey):
        """ Allows the `VolttronCentralPlatform` to be managed.

        From the web perspective this should be after the user has specified
        that a user has blessed an agent to be able to be managed.

        When the user enters a discovery address in `VolttronCentral` it is
        implied that the user wants to manage a platform.

        :returns publickey of the `VolttronCentralPlatform`
        """
        _log.info('Manage request from address: {} serverkey: {}'.format(
            address, vcserverkey))

        if self._managed:
            raise AlreadyManagedError()

        parsedaddress = urlparse.urlparse(address)

        if 'ipc://' == address[:6].lower():
            self._agent_connected_to_vc = self
        else:
            # Attempt to connect to the passed address and serverkey.
            self._agent_connected_to_vc = build_agent(
                address=address, serverkey=vcserverkey,
                publickey=self.core.publickey, secretkey=self.core.secretkey)

        version, peer, identity = self._agent_connected_to_vc.vip.hello().get(
            timeout=30)

        if not self == self._agent_connected_to_vc:
            # Add the vcpublickey to the auth file.
            entry = AuthEntry(
                credentials="CURVE:{}".format(vcpublickey),
                capabilities=['manager'])  # , address=parsedaddress.hostname)
            authfile = AuthFile()
            authfile.add(entry)
        self._managed = True
        self.core.spawn_later(2, self._publish_agent_list_to_vc)
        self.core.spawn_later(2, self._publish_stats)
        return self.core.publickey
Esempio n. 15
0
def test_forwarding(volttron_instance1_encrypt, volttron_instance2_encrypt):
    global FORWARDER_CONFIG
    tf = tempfile.NamedTemporaryFile()
    tf2 = tempfile.NamedTemporaryFile()
    tf3 = tempfile.NamedTemporaryFile()
    ks = KeyStore(tf.name)
    ks.generate()
    ks2 = KeyStore(tf2.name)
    ks2.generate()
    ks3 = KeyStore(tf2.name)
    ks3.generate()

    wrap1 = volttron_instance1_encrypt
    wrap2 = volttron_instance2_encrypt

    authfile1 = AuthFile(wrap1.volttron_home+"/auth.json")
    entry1 = AuthEntry(
        credentials="CURVE:{}".format(ks3.public())
    )
    authfile1.add(entry1)

    authfile = AuthFile(wrap2.volttron_home+"/auth.json")
    entry = AuthEntry(
        credentials="CURVE:{}".format(ks.public()))
    authfile.add(entry)
    entry = AuthEntry(
        credentials="CURVE:{}".format(ks2.public()))
    authfile.add(entry)

    forward_to_vip = "{}?serverkey={}&publickey={}&secretkey={}".format(
        wrap2.vip_address, wrap2.publickey, ks.public(), ks.secret()
    )

    FORWARDER_CONFIG["destination-vip"] = forward_to_vip
    forwarder_config = FORWARDER_CONFIG
    print("THE CONFIG = {}".format(forwarder_config))

    wrap1.install_agent(
        agent_dir="services/core/ForwardHistorian",
        config_file=forwarder_config
    )

    connect_to_wrap2 = "{}?serverkey={}&publickey={}&secretkey={}".format(
        wrap2.vip_address, wrap2.publickey, ks2.public(), ks2.secret()
    )

    connect_to_wrap1 = "{}?serverkey={}&publickey={}&secretkey={}".format(
        wrap1.vip_address, wrap1.publickey, ks3.public(), ks3.secret()
    )

    agent_connected1 = wrap1.build_agent(address=connect_to_wrap1)
    agent_connected2 = wrap2.build_agent(address=connect_to_wrap2)

    message = ''
    agent_connected2.vip.pubsub.subscribe('pubsub', '', callback=onmessage)
    gevent.sleep(0.2)

    do_publish(agent1=agent_connected1)
    gevent.sleep(1)
    assert allforwardedmessage
Esempio n. 16
0
def test_forwarding(volttron_instance1_encrypt, volttron_instance2_encrypt):
    global FORWARDER_CONFIG
    tf = tempfile.NamedTemporaryFile()
    tf2 = tempfile.NamedTemporaryFile()
    tf3 = tempfile.NamedTemporaryFile()
    ks = KeyStore(tf.name)
    ks.generate()
    ks2 = KeyStore(tf2.name)
    ks2.generate()
    ks3 = KeyStore(tf2.name)
    ks3.generate()

    wrap1 = volttron_instance1_encrypt
    wrap2 = volttron_instance2_encrypt

    authfile1 = AuthFile(wrap1.volttron_home + "/auth.json")
    entry1 = AuthEntry(credentials="CURVE:{}".format(ks3.public()))
    authfile1.add(entry1)

    authfile = AuthFile(wrap2.volttron_home + "/auth.json")
    entry = AuthEntry(credentials="CURVE:{}".format(ks.public()))
    authfile.add(entry)
    entry = AuthEntry(credentials="CURVE:{}".format(ks2.public()))
    authfile.add(entry)

    forward_to_vip = "{}?serverkey={}&publickey={}&secretkey={}".format(
        wrap2.vip_address, wrap2.publickey, ks.public(), ks.secret())

    FORWARDER_CONFIG["destination-vip"] = forward_to_vip
    forwarder_config = FORWARDER_CONFIG
    print("THE CONFIG = {}".format(forwarder_config))

    wrap1.install_agent(agent_dir="services/core/ForwardHistorian",
                        config_file=forwarder_config)

    connect_to_wrap2 = "{}?serverkey={}&publickey={}&secretkey={}".format(
        wrap2.vip_address, wrap2.publickey, ks2.public(), ks2.secret())

    connect_to_wrap1 = "{}?serverkey={}&publickey={}&secretkey={}".format(
        wrap1.vip_address, wrap1.publickey, ks3.public(), ks3.secret())

    agent_connected1 = wrap1.build_agent(address=connect_to_wrap1)
    agent_connected2 = wrap2.build_agent(address=connect_to_wrap2)

    message = ''
    agent_connected2.vip.pubsub.subscribe('pubsub', '', callback=onmessage)
    gevent.sleep(0.2)

    do_publish(agent1=agent_connected1)
    gevent.sleep(1)
    assert allforwardedmessage
Esempio n. 17
0
    def _periodic_attempt_registration(self):

        _log.debug("periodic attempt to register.")
        if self._scheduled_connection_event is not None:
            # This won't hurt anything if we are canceling ourselves.
            self._scheduled_connection_event.cancel()

        if not self.enable_registration:
            _log.debug('Registration of vcp is not enabled.')
            next_update_time = self._next_update_time()

            self._scheduled_connection_event = self.core.schedule(
                next_update_time, self._periodic_attempt_registration)
            return

        try:
            vc = self.get_vc_connection()
            if vc is None:
                _log.debug("vc not connected")
                return
            local_address = self.current_config.get(
                'local_external_addresses')[0]
            if not vc.call("is_registered", address=local_address):
                _log.debug("platform agent is not registered.")
                self.registration_state = RegistrationStates.NotRegistered

            if self.registration_state == RegistrationStates.NotRegistered:
                vc_agent_publickey = vc.call("get_publickey")
                _log.debug(
                    'vc agent publickey is {}'.format(vc_agent_publickey))
                assert vc_agent_publickey and len(vc_agent_publickey) == 43
                authfile = AuthFile()
                # find_by_credentials returns a list.
                entries = authfile.find_by_credentials(vc_agent_publickey)
                if entries is not None and len(entries) > 0:
                    entry = entries[0]
                    if "manage" not in entry.capabilities:
                        _log.debug("Updating vc capability.")
                        entry.add_capabilities("manager")
                        authfile.add(entry, overwrite=True)
                else:
                    _log.debug('Adding vc publickey to auth')
                    entry = AuthEntry(credentials=vc_agent_publickey,
                                      capabilities=['manager'],
                                      comments="Added by VCP",
                                      user_id="vc")
                    authfile = AuthFile()
                    authfile.add(entry)

                local_address = self.current_config.get(
                    'local_external_addresses')[0]
                local_name = self.current_config.get('local_instance_name',
                                                     local_address)
                local_serverkey = self.current_config.get('local_serverkey')
                vc_address = self.current_config.get(
                    'volttron_central_address')

                _log.debug("Registering with vc from vcp.")
                _log.debug("Instance is named: {}".format(local_name))
                _log.debug("Local Address is: {}".format(local_address))
                _log.debug("VC Address is: {}".format(vc_address))

                vc.call('register_instance',
                        address=local_address,
                        display_name=local_name,
                        vcpserverkey=local_serverkey,
                        vcpagentkey=self.core.publickey)

            else:
                _log.debug("Current platform registration state: {}".format(
                    self.registration_state))
        except Unreachable as e:
            _log.error("Couldn't connect to volttron.central. {}".format(
                self.current_config.get('volttron_central_address')))
        except ValueError as e:
            _log.error(e.message)
        except Exception as e:
            _log.error("Error: {}".format(e.args))
        except gevent.Timeout as e:
            _log.error("timout occured connecting to remote platform.")
        finally:
            _log.debug('Scheduling next periodic call')
            next_update_time = self._next_update_time()

            self._scheduled_connection_event = self.core.schedule(
                next_update_time, self._periodic_attempt_registration)
Esempio n. 18
0
def add_to_auth(volttron_home, publickey, capabilities=None):
    authfile = AuthFile(os.path.join(volttron_home, 'auth.json'))
    entry = AuthEntry(
        credentials=publickey, mechanism="CURVE", capabilities=capabilities
    )
    authfile.add(entry, overwrite=True)
Esempio n. 19
0
VIRGINIA TECH – ADVANCED RESEARCH INSTITUTE
under Contract DE-EE0006352

#__author__ = "BEMOSS Team"
#__credits__ = ""
#__version__ = "2.0"
#__maintainer__ = "BEMOSS Team"
#__email__ = "*****@*****.**"
#__website__ = "www.bemoss.org"
#__created__ = "2014-09-12 12:04:50"
#__lastUpdated__ = "2016-03-14 11:23:33"
'''
import os
path = os.environ.get('VOLTTRON_HOME')

from volttron.platform.auth import AuthEntry, AuthFile

if __name__ == "__main__":

    print "Adding new Auth entry"
    auth_file = AuthFile(path + '/auth.json')
    entry = AuthEntry(credentials='NULL',
                      comments='second',
                      user_id="BEMOSSAGENT",
                      capabilities=["BEMOSS_BASIC_AGENT"])
    auth_file.add(entry)
    print "NEW AUTH IS ADDED BY BEMOSS"

    # p = Popen([ "volttron-ctl auth-update 0 ;"], stdin=PIPE, shell=True)
    # p.communicate("\n".join(["", "BEMOSSAGENT", "", "", "", "", "", "", "", "", ""]))
    # print "finished adding userid"
Esempio n. 20
0
    def _register_instance(self,
                           discovery_address,
                           display_name=None,
                           provisional=False):
        """ Register an instance with VOLTTRON Central based on jsonrpc.

        NOTE: This method is meant to be called from the jsonrpc method.

        The registration of the instance will fail in the following cases:
        - no discoverable instance at the passed uri
        - no platform.agent installed at the discoverable instance
        - is a different volttron central managing the discoverable
          instance.

        If the display name is not set then the display name becomes the
        same as the discovery_address.  This will be used in the
        volttron central ui.

        :param discovery_address: A ip:port for an instance of volttron
               discovery.
        :param display_name:
        :return: dictionary:
            The dictionary will hold either an error object or a result
            object.
        """

        _log.info('Attempting to register name: {} with address: {}'.format(
            display_name, discovery_address))

        try:
            discovery_response = DiscoveryInfo.request_discovery_info(
                discovery_address)
        except DiscoveryError as e:
            return {'error': {'code': DISCOVERY_ERROR, 'message': e.message}}

        pa_instance_serverkey = discovery_response.serverkey
        pa_vip_address = discovery_response.vip_address

        assert pa_instance_serverkey
        _log.debug('connecting to pa_instance')
        try:
            connected_to_pa = ConnectedPlatform(
                address=pa_vip_address,
                serverkey=pa_instance_serverkey,
                secretkey=self.core.secretkey,
                publickey=self.core.publickey)
            connected_to_pa.connect()
            if not connected_to_pa.is_connected():
                return {
                    'error': {
                        'code': UNABLE_TO_REGISTER_INSTANCE,
                        'message':
                        'Could not connect to {}'.format(pa_vip_address)
                    }
                }
        except gevent.Timeout:
            return {
                'error': {
                    'code': UNABLE_TO_REGISTER_INSTANCE,
                    'message': 'Could not connect to {}'.format(pa_vip_address)
                }
            }
        except Exception as ex:
            return {
                'error': {
                    'code': UNHANDLED_EXCEPTION,
                    'message': ex.message
                }
            }

        _log.debug('Connected to address')
        peers = connected_to_pa.agent.vip.peerlist().get(timeout=30)
        if VOLTTRON_CENTRAL_PLATFORM not in peers:
            connected_to_pa.core.stop()
            return {
                'error': {
                    'code': UNABLE_TO_REGISTER_INSTANCE,
                    'message':
                    '{} not present.'.format(VOLTTRON_CENTRAL_PLATFORM)
                }
            }

        # The call to manage should return a public key for that agent
        result = connected_to_pa.agent.vip.rpc.call(
            VOLTTRON_CENTRAL_PLATFORM, 'manage', self._web_info.vip_address,
            self._web_info.serverkey, self.core.publickey).get(timeout=30)

        # Magic number 43 is the length of a encoded public key.
        if len(result) != 43:
            return {
                'error': {
                    'code':
                    UNABLE_TO_REGISTER_INSTANCE,
                    'message':
                    'Invalid publickey returned from {}'.format(
                        VOLTTRON_CENTRAL_PLATFORM)
                }
            }

        # Add the pa's public key so it can connect back to us.
        auth_file = AuthFile()
        auth_entry = AuthEntry(credentials="CURVE:{}".format(result),
                               capabilities=['managing'])
        auth_file.add(auth_entry)

        # TODO: figure out if we are local or not

        entry = PlatformRegistry.build_entry(pa_vip_address,
                                             pa_instance_serverkey,
                                             discovery_address, display_name,
                                             False)

        self._registry.register(entry)
        self._pa_agents[entry.platform_uuid] = connected_to_pa
        _log.debug("Adding {}".format(entry.platform_uuid))
        instance_name = display_name if display_name else discovery_address
        context = 'Registered instance {}'.format(instance_name)
        connected_to_pa.agent.vip.rpc.call(
            VOLTTRON_CENTRAL_PLATFORM,
            'reconfigure',
            platform_uuid=entry.platform_uuid).get(timeout=30)

        return {'status': 'SUCCESS', 'context': context}
Esempio n. 21
0
 def _append_allow_curve_key(self, publickey):
     entry = AuthEntry(credentials="CURVE:{}".format(publickey))
     authfile = AuthFile(self.volttron_home+"/auth.json")
     authfile.add(entry)
Esempio n. 22
0
    def _vc_connection(self):
        """ Attempt to connect to volttron central management console.

        The attempts will be done in the following order.

        1. if peer is vc register with it.
        2. volttron-central-tcp and serverkey
        2. volttron-central-http (looks up tcp and serverkey)
        3. volttron-central-ipc

        :param sender:
        :param kwargs:
        :return:
        """

        assert self._agent_started, "cannot be called before onstart signal"

        if self._volttron_central_connection:
            # if connected return the connection.
            if self._volttron_central_connection.is_connected(5):
                _log.debug('Returning connection')
                return self._volttron_central_connection

            _log.debug("Resetting connection as the peer wasn't responding.")
            # reset the connection so we can try it again below.
            self._volttron_central_connection.kill()
            self._volttron_central_connection = None

        # First check to see if there is a peer with a volttron.central
        # identity, if there is use it as the manager of the platform.
        peers = self.vip.peerlist().get(timeout=5)
        if VOLTTRON_CENTRAL in peers:
            _log.debug('VC is a local peer.')
            self._volttron_central_connection = Connection(
                self.core.address, VOLTTRON_CENTRAL)
            if self._volttron_central_connection.is_connected() and \
                    self._volttron_central_connection.is_peer_connected():
                _log.debug("Connection has been established to local peer.")
            return self._volttron_central_connection

        # If we have an http address for volttron central, but haven't
        # looked up the address yet, then look up and set the address from
        # volttron central discovery.
        if self._volttron_central_http_address is not None and \
                        self._volttron_central_tcp_address is None and \
                        self._volttron_central_serverkey is None:

            _log.debug('Using discovery to lookup tcp connection')

            response = requests.get("{}/discovery/".format(
                self._volttron_central_http_address))

            if response.ok:
                jsonresp = response.json()
                entry = AuthEntry(credentials="/.*/",
                                  capabilities=['manager']
                                  #,
                                  #address=jsonresp['vip-address']
                                  )
                authfile = AuthFile(get_home() + "/auth.json")
                authfile.add(entry)
                self._volttron_central_tcp_address = jsonresp['vip-address']
                self._volttron_central_serverkey = jsonresp['serverkey']

        # First see if we are able to connect via tcp with the serverkey.
        if self._volttron_central_tcp_address is not None and \
                self._volttron_central_serverkey is not None:
            _log.debug('Connecting to volttron central using tcp.')

            vc_conn = Connection(address=self._volttron_central_tcp_address,
                                 peer=VOLTTRON_CENTRAL,
                                 serverkey=self._volttron_central_serverkey,
                                 publickey=self.core.publickey,
                                 secretkey=self.core.secretkey)

            if not vc_conn.is_connected(5):
                raise ValueError("Unable to connect to remote platform")

            if not vc_conn.is_peer_connected(5):
                raise ValueError(
                    "Peer: {} unavailable on remote platform.".format(
                        VOLTTRON_CENTRAL))

            #TODO Only add a single time for this address.
            if self._volttron_central_publickey:
                # Add the vcpublickey to the auth file.
                entry = AuthEntry(credentials=self._volttron_central_publickey,
                                  capabilities=['manager'])
                authfile = AuthFile()
                authfile.add(entry)

            self._volttron_central_connection = vc_conn

            return self._volttron_central_connection

        # Next see if we have a valid ipc address (Not Local though)
        if self._volttron_central_ipc_address is not None:
            self._volttron_central_connection = Connection(
                address=self._volttron_central_ipc_address,
                peer=VOLTTRON_CENTRAL)

            return self._volttron_central_connection
Esempio n. 23
0
    def _register_instance(self, discovery_address, display_name=None,
                           provisional=False):
        """ Register an instance with VOLTTRON Central based on jsonrpc.

        NOTE: This method is meant to be called from the jsonrpc method.

        The registration of the instance will fail in the following cases:
        - no discoverable instance at the passed uri
        - no platform.agent installed at the discoverable instance
        - is a different volttron central managing the discoverable
          instance.

        If the display name is not set then the display name becomes the
        same as the discovery_address.  This will be used in the
        volttron central ui.

        :param discovery_address: A ip:port for an instance of volttron
               discovery.
        :param display_name:
        :return: dictionary:
            The dictionary will hold either an error object or a result
            object.
        """

        _log.info(
            'Attempting to register name: {} with address: {}'.format(
                display_name, discovery_address))

        try:
            discovery_response = DiscoveryInfo.request_discovery_info(
                discovery_address)
        except DiscoveryError as e:
            return {
                'error': {
                    'code': DISCOVERY_ERROR, 'message': e.message
                }}

        pa_instance_serverkey = discovery_response.serverkey
        pa_vip_address = discovery_response.vip_address

        assert pa_instance_serverkey
        _log.debug('connecting to pa_instance')
        try:
            connected_to_pa = ConnectedPlatform(
                address=pa_vip_address, serverkey=pa_instance_serverkey,
                secretkey=self.core.secretkey,
                publickey=self.core.publickey
            )
            connected_to_pa.connect()
            if not connected_to_pa.is_connected():
                return {
                    'error': {
                        'code': UNABLE_TO_REGISTER_INSTANCE,
                        'message': 'Could not connect to {}'
                            .format(pa_vip_address)
                    }}
        except gevent.Timeout:
            return {
                'error': {
                    'code': UNABLE_TO_REGISTER_INSTANCE,
                    'message': 'Could not connect to {}'
                        .format(pa_vip_address)
                }}
        except Exception as ex:
            return {'error': {'code': UNHANDLED_EXCEPTION,
                              'message': ex.message
                              }}

        _log.debug('Connected to address')
        peers = connected_to_pa.agent.vip.peerlist().get(timeout=30)
        if VOLTTRON_CENTRAL_PLATFORM not in peers:
            connected_to_pa.core.stop()
            return {'error': {'code': UNABLE_TO_REGISTER_INSTANCE,
                              'message': '{} not present.'.format(
                                  VOLTTRON_CENTRAL_PLATFORM)
                              }}

        # The call to manage should return a public key for that agent
        result = connected_to_pa.agent.vip.rpc.call(
            VOLTTRON_CENTRAL_PLATFORM, 'manage', self._web_info.vip_address,
            self._web_info.serverkey, self.core.publickey).get(timeout=30)

        # Magic number 43 is the length of a encoded public key.
        if len(result) != 43:
            return {'error': {'code': UNABLE_TO_REGISTER_INSTANCE,
                              'message': 'Invalid publickey returned from {}'
                                  .format(VOLTTRON_CENTRAL_PLATFORM)
                              }}

        # Add the pa's public key so it can connect back to us.
        auth_file = AuthFile()
        auth_entry = AuthEntry(credentials="CURVE:{}".format(result),
                               capabilities=['managing']
                               )
        auth_file.add(auth_entry)

        # TODO: figure out if we are local or not

        entry = PlatformRegistry.build_entry(
            pa_vip_address, pa_instance_serverkey, discovery_address,
            display_name, False)

        self._registry.register(entry)
        self._pa_agents[entry.platform_uuid] = connected_to_pa
        _log.debug("Adding {}".format(entry.platform_uuid))
        instance_name = display_name if display_name else discovery_address
        context = 'Registered instance {}'.format(instance_name)
        connected_to_pa.agent.vip.rpc.call(
            VOLTTRON_CENTRAL_PLATFORM, 'reconfigure',
            platform_uuid=entry.platform_uuid).get(timeout=30)

        return {'status': 'SUCCESS', 'context': context}
Esempio n. 24
0
 def allow_all_connections(self):
     """ Add a CURVE:.* entry to the auth.json file.
     """
     entry = AuthEntry(credentials="/CURVE:.*/")
     authfile = AuthFile(self.volttron_home+"/auth.json")
     authfile.add(entry)
Esempio n. 25
0
 def allow_all_connections(self):
     """ Add a CURVE:.* entry to the auth.json file.
     """
     entry = AuthEntry(credentials="/CURVE:.*/")
     authfile = AuthFile(self.volttron_home + "/auth.json")
     authfile.add(entry)
Esempio n. 26
0
 def _append_allow_curve_key(self, publickey):
     entry = AuthEntry(credentials="CURVE:{}".format(publickey))
     authfile = AuthFile(self.volttron_home + "/auth.json")
     authfile.add(entry)
Esempio n. 27
0
def add_to_auth(volttron_home, publickey, capabilities=None):
    authfile = AuthFile(os.path.join(volttron_home, 'auth.json'))
    entry = AuthEntry(credentials=publickey,
                      mechanism="CURVE",
                      capabilities=capabilities)
    authfile.add(entry, overwrite=True)
Esempio n. 28
0
def add_to_auth(volttron_home, publickey, capabilities=None):
    authfile = AuthFile(os.path.join(volttron_home, 'auth.json'))
    entry = AuthEntry(
        credentials="CURVE:{}".format(publickey), capabilities=capabilities
    )
    authfile.add(entry)