Exemplo n.º 1
0
def test_invalid_auth_entries(auth_file_platform_tuple):
    auth_file = auth_file_platform_tuple
    with pytest.raises(AuthEntryInvalid):
        AuthEntry()
    with pytest.raises(AuthEntryInvalid):
        AuthEntry(credentials='invalid key')
    with pytest.raises(AuthEntryInvalid):
        AuthEntry(mechanism='Not NULL or PLAIN or CURVE')
Exemplo n.º 2
0
def test_invalid_auth_entries(auth_file_platform_tuple):
    auth_file, _ = auth_file_platform_tuple
    with pytest.raises(AuthEntryInvalid):
        AuthEntry()
    with pytest.raises(AuthEntryInvalid):
        AuthEntry(credentials='CURVE:invalid key')
    with pytest.raises(AuthEntryInvalid):
        AuthEntry(credentials='Not NULL or PLAIN: or CURVE:')
Exemplo n.º 3
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
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)
Exemplo n.º 5
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
Exemplo n.º 6
0
def test_groups_and_roles(auth_file_platform_tuple):
    auth_file = auth_file_platform_tuple
    cred = 'C'*43
    auth_file.add(AuthEntry(credentials=cred, groups=['group_1'],
                            roles=['role_b']))
    auth_file.load()
    # This entry hasn not been granted any capabilities
    results = auth_file.find_by_credentials(cred)
    assert len(results) == 1
    entry = results[0]
    assert not set(entry.capabilities)

    # Add roles and groups to the auth file
    roles = {
        'role_a': ['cap_a_1', 'cap_a_2'],
        'role_b': ['cap_b_1'],
        'role_c': ['cap_c_1'],
        'role_d': ['cap_d_1']
    }
    groups = {
        'group_1': ['role_a', 'role_c'],
        'group_2': ['role_b']
    }
    auth_file.set_roles(roles)
    auth_file.load()
    auth_file.set_groups(groups)
    auth_file.load()
    # Now the entry has inherited capabilities from its roles and groups
    results = auth_file.find_by_credentials(cred)
    assert len(results) == 1
    entry = results[0]
    assert set(entry.capabilities) == set(['cap_a_1', 'cap_a_2', 'cap_b_1',
                                           'cap_c_1'])
Exemplo n.º 7
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"))
Exemplo n.º 8
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
Exemplo n.º 9
0
def test_find_by_credentials(auth_file_platform_tuple):
    auth_file = auth_file_platform_tuple[0]
    cred1 = 'A' * 43
    cred2 = 'B' * 43
    auth_file.add(AuthEntry(domain='test1', credentials=cred1))
    auth_file.add(AuthEntry(domain='test2', credentials=cred1))
    auth_file.add(AuthEntry(domain='test3', credentials=cred2))

    # find non-regex creds
    results = auth_file.find_by_credentials(cred1)
    assert len(results) == 2
    domains = [entry.domain for entry in results]
    assert 'test1' in domains and 'test2' in domains

    # try to find non-existing creds
    results = auth_file.find_by_credentials('C' * 43)
    assert len(results) == 0
Exemplo n.º 10
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
Exemplo n.º 11
0
def auth_entry3():
    return AuthEntry(domain='domain3',
                     address='tcp://127.0.0.3',
                     credentials='B' * 43,
                     user_id='user3',
                     groups=['group3'],
                     roles=['role3'],
                     capabilities=['cap3'],
                     comments='com3',
                     enabled=False)
Exemplo n.º 12
0
def auth_entry1():
    return AuthEntry(domain='domain1',
                     address='tcp://127.0.0.1',
                     mechanism='NULL',
                     user_id='user1',
                     groups=['group1'],
                     roles=['role1'],
                     capabilities=['cap1'],
                     comments='com1',
                     enabled=True)
Exemplo n.º 13
0
def auth_entry2():
    return AuthEntry(domain='domain2',
                     address='tcp://127.0.0.2',
                     credentials='A' * 43,
                     user_id='user2',
                     groups=['group2'],
                     roles=['role2'],
                     capabilities=['cap2'],
                     comments='com2',
                     enabled=False)
Exemplo n.º 14
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")
Exemplo n.º 15
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"
Exemplo n.º 16
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
Exemplo n.º 17
0
def auth_entry_only_creds():
    return AuthEntry(credentials='B'*43)
Exemplo n.º 18
0
import os
import re
import subprocess
import pytest
from mock import MagicMock
from volttrontesting.utils.utils import AgentMock
from volttron.platform.vip.agent import Agent
from volttron.platform.auth import AuthService
from volttron.platform.auth import AuthEntry
from volttron.platform import jsonapi

_auth_entry1 = AuthEntry(domain='test1_domain',
                         address='test1_address',
                         mechanism='NULL',
                         user_id='test1_userid',
                         groups=['test1_group1', 'test1_group2'],
                         roles=['test1_role1', 'test1_role2'],
                         capabilities=['test1_cap1', 'test1_cap2'],
                         comments='test1 comment',
                         enabled=True)

_auth_entry2 = AuthEntry(domain='test2_domain',
                         address='test2_address',
                         mechanism='NULL',
                         user_id='test2_userid',
                         groups=['test2_group1', 'test2_group2'],
                         roles=['test2_role1', 'test2_role2'],
                         capabilities=['test2_cap1', 'test2_cap2'],
                         comments='test2 comment',
                         enabled=False)
Exemplo 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"
Exemplo n.º 20
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)
Exemplo n.º 21
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)
Exemplo 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
Exemplo n.º 23
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)
Exemplo n.º 24
0
import pytest
from mock import MagicMock

from volttrontesting.platform.auth_tests.conftest import assert_auth_entries_same
from volttrontesting.utils.platformwrapper import with_os_environ
from volttrontesting.utils.utils import AgentMock
from volttron.platform.vip.agent import Agent
from volttron.platform.auth import AuthService
from volttron.platform.auth import AuthEntry
from volttron.platform import jsonapi

_auth_entry1 = AuthEntry(domain='test1_domain',
                         address='test1_address',
                         mechanism='NULL',
                         user_id='test1_userid',
                         identity='test_userid',
                         groups=['test1_group1', 'test1_group2'],
                         roles=['test1_role1', 'test1_role2'],
                         capabilities=['test1_cap1', 'test1_cap2'],
                         comments='test1 comment',
                         enabled=True)

_auth_entry2 = AuthEntry(domain='test2_domain',
                         address='test2_address',
                         mechanism='NULL',
                         user_id='test2_userid',
                         identity='test2_userid',
                         groups=['test2_group1', 'test2_group2'],
                         roles=['test2_role1', 'test2_role2'],
                         capabilities=['test2_cap1', 'test2_cap2'],
                         comments='test2 comment',
                         enabled=True)
Exemplo n.º 25
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}
Exemplo n.º 26
0
import json
import os
import re
import subprocess

import pytest

from volttron.platform.auth import AuthEntry

_auth_entry1 = AuthEntry(domain='test1_domain',
                         address='test1_address',
                         credentials='NULL',
                         user_id='test1_userid',
                         groups=['test1_group1', 'test1_group2'],
                         roles=['test1_role1', 'test1_role2'],
                         capabilities=['test1_cap1', 'test1_cap2'],
                         comments='test1 comment',
                         enabled=True)

_auth_entry2 = AuthEntry(domain='test2_domain',
                         address='test2_address',
                         credentials='NULL',
                         user_id='test2_userid',
                         groups=['test2_group1', 'test2_group2'],
                         roles=['test2_role1', 'test2_role2'],
                         capabilities=['test2_cap1', 'test2_cap2'],
                         comments='test2 comment',
                         enabled=False)


def get_env(platform):
Exemplo n.º 27
0
def _main():
    """ Routine for configuring an insalled volttron instance.

    The function interactively sets up the instance for working with volttron
    central and the discovery service.
    """
    volttron_home = _os.path.normpath(expandall(
        _os.environ.get('VOLTTRON_HOME', '~/.volttron')))
    _os.environ['VOLTTRON_HOME'] = volttron_home
    if not _os.path.exists(volttron_home):
        _os.makedirs(volttron_home, 0o755)

    y_or_n = ('Y', 'N', 'y', 'n')
    y = ('Y', 'y')
    n = ('N', 'n')
    print('\nYour VOLTTRON_HOME currently set to: {}'.format(volttron_home))
    t = ('\nIs this the volttron you are attempting to setup? [Y]',
         y_or_n,
         'Y')
    if not prompt_response(t) in y:
        print(
            '\nPlease execute with VOLTRON_HOME=/your/path volttron-cfg to '
            'modify VOLTTRON_HOME.\n')
        return
    t = ('\nIs this instance discoverable (Y/N)? [N] ', y_or_n, 'N')
    _explain_discoverable()
    is_discoverable = prompt_response(t) in y

    if is_discoverable:
        t = ('\nWhat is the external ipv4 address for this instance? '
             '[127.0.0.1]: ', None, '127.0.0.1')
        external_ip = prompt_response(t)
        t = ('What is the vip port this instance? [22916] ',)
        vip_port = prompt_response(t)
        if not vip_port:
            vip_port = 22916

        t = ('\nWhat is the port for discovery? [8080] ',)
        external_port = prompt_response(t)
        if not external_port:
            external_port = 8080
        t = (
            '\nWhich IP addresses are allowed to discover this instance? '
            '[/127.*/] ', None, '/127.*/')
        ip_allowed_to_discover = prompt_response(t)
        AuthFile().add(AuthEntry(address=ip_allowed_to_discover,
                                 credentials='/CURVE:.*/'))

        t = ('\nIs this instance a volttron central (Y/N)? [N] ', y_or_n, 'N')
        do_install_vc = prompt_response(t) in y
        do_vc_autostart = True
        do_platform_autostart = True
        if do_install_vc:
            t = ('\nShould volttron central autostart(Y/N)? [Y] ',
                 y_or_n, 'Y')
            do_vc_autostart = prompt_response(t) in y

            t = ('\nInclude volttron central platform agent on '
                 'volttron central? [Y]', y_or_n, 'Y')
            do_install_platform = prompt_response(t) in y
        else:
            do_install_platform = True
            t = ('\nAddress of volttron central? [127.0.0.1]: ', None,
                 '127.0.0.1')
            vc_ipaddress = prompt_response(t)
            should_resolve = True
            first = True
            t = ('Port of volttron central? [8080] ',)
            vc_port = prompt_response(t)
            if not vc_port:
                vc_port = 8080
            while not _resolvable(vc_ipaddress, vc_port) and should_resolve:
                print("Couldn't resolve {}:{}".format(vc_ipaddress, vc_port))
                t2 = (
                    '\nShould volttron central be resolvable now? [Y] ', y_or_n,
                    'Y')
                if first:
                    should_resolve = prompt_response(t2) in ('y', 'Y')
                    first = False

                if should_resolve:
                    t = ('\nAddress of volttron central? ',)
                    vc_ipaddress = prompt_response(t)
                    t = ('\nPort of volttron central? ',)
                    vc_port = prompt_response(t)

        if do_install_platform:
            t = ('\nShould platform agent autostart(Y/N)? [Y] ', y_or_n, 'Y')
            do_platform_autostart = prompt_response(t) in y

        external_uri = "tcp://{}:{}".format(external_ip, vip_port)
        bind_web_address = "http://{}:{}".format(external_ip,
                                                 external_port)
        try:
            vc_web_address = "http://{}:{}".format(vc_ipaddress, vc_port)
            _make_configuration(external_uri, bind_web_address,
                                vc_web_address)

        # if vc_ipaddres isn't defined
        # only happens on volttron central.
        except UnboundLocalError:
            _make_configuration(external_uri, bind_web_address)

        t = ('\nShould install sqlite platform historian? [N]', y_or_n, n)
        do_install_platform_historian = prompt_response(t) in y

        do_historian_autostart = True
        if do_install_platform_historian:
            t = ('\nShould historian agent autostart(Y/N)? [Y] ', y_or_n, 'Y')
            do_historian_autostart = prompt_response(t) in y

        # in order to install agents we need to start the platform.
        _start_platform()
        _install_agents((do_install_vc, do_vc_autostart),
                        (do_install_platform, do_platform_autostart),
                        (do_install_platform_historian,
                         do_historian_autostart))
        _shutdown_platform()
        print('Finished configuration\n')
        print('You can now start you volttron instance.\n')
        print('If you need to change the instance configuration you can edit')
        print('the config file at {}/{}\n'.format(volttron_home, 'config'))
Exemplo n.º 28
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)
Exemplo n.º 29
0
 def _append_allow_curve_key(self, publickey):
     entry = AuthEntry(credentials="CURVE:{}".format(publickey))
     authfile = AuthFile(self.volttron_home + "/auth.json")
     authfile.add(entry)