コード例 #1
0
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)
コード例 #2
0
    def build_connection(self,
                         peer=None,
                         address=None,
                         identity=None,
                         publickey=None,
                         secretkey=None,
                         serverkey=None,
                         **kwargs):

        if self.encrypt:
            self.allow_all_connections()

        if address is None:
            address = self.vip_address
            serverkey = self.serverkey

        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()
        if self.encrypt:
            conn = Connection(address=address,
                              peer=peer,
                              publickey=publickey,
                              secretkey=secretkey,
                              serverkey=serverkey,
                              volttron_home=self.volttron_home)
        else:
            conn = Connection(address=self.local_vip_address,
                              peer=peer,
                              volttron_home=self.volttron_home)
        return conn
コード例 #3
0
def setup_control_connection(request, get_volttron_instances):
    """ Creates a single instance of VOLTTRON for testing purposes
    """
    global wrapper, control_connection

    wrapper = get_volttron_instances(1)

    request.addfinalizer(wrapper.shutdown_platform)

    assert wrapper
    assert wrapper.is_running()

    if get_volttron_instances.param == 'encrypted':
        if wrapper.encrypt:
            wrapper.allow_all_connections()
        # Connect using keys
        ks = KeyStore()
        ks.generate()

        control_connection = Connection(address=wrapper.vip_address,
                                        peer=CONTROL,
                                        serverkey=wrapper.serverkey,
                                        publickey=ks.public(),
                                        secretkey=ks.secret())
    else:
        control_connection = Connection(address=wrapper.local_vip_address,
                                        peer=CONTROL)
    # Sleep a couple seconds to wait for things to startup
    gevent.sleep(2)
    return wrapper, control_connection
コード例 #4
0
ファイル: platformwrapper.py プロジェクト: cbs-iiith/volttron
    def build_agent(self, address=None, should_spawn=True, identity=None,
                    publickey=None, secretkey=None, serverkey=None,
                    generatekeys=False, **kwargs):
        """ Build an agent connnected to the passed bus.

        By default the current instance that this class wraps will be the
        vip address of the agent.

        :param address:
        :param should_spawn:
        :param identity:
        :param publickey:
        :param secretkey:
        :param serverkey:
        :return:
        """
        self.logit("Building generic agent.")

        use_ipc = kwargs.pop('use_ipc', False)
        if address is None:
            if use_ipc:
                self.logit('Using IPC vip-address')
                address = "ipc://@"+self.volttron_home+"/run/vip.socket"
            else:
                self.logit('Using vip-address '+self.vip_address)
                address = self.vip_address

        if generatekeys:
            self.logit('generating new public secret key pair')
            tf = tempfile.NamedTemporaryFile()
            ks = KeyStore(tf.name)
            ks.generate()
            publickey = ks.public()
            secretkey = ks.secret()

        if publickey and not serverkey:
            self.logit('using instance serverkey: {}'.format(self.publickey))
            serverkey = self.publickey

        agent = Agent(address=address, identity=identity, publickey=publickey,
                      secretkey=secretkey, serverkey=serverkey, **kwargs)
        self.logit('platformwrapper.build_agent.address: {}'.format(address))

        # Automatically add agent's credentials to auth.json file
        if publickey:
            self.logit('Adding publickey to auth.json')
            gevent.spawn(self._append_allow_curve_key, publickey)
            gevent.sleep(0.1)


        if should_spawn:
            self.logit('platformwrapper.build_agent spawning')
            event = gevent.event.Event()
            gevent.spawn(agent.core.run, event)#.join(0)
            event.wait(timeout=2)

            hello = agent.vip.hello().get(timeout=.3)
            self.logit('Got hello response {}'.format(hello))

        return agent
コード例 #5
0
ファイル: build_agent.py プロジェクト: miraabid/bemoss
def build_agent_with_key(platform, identity=None):
    """Create an agent instance that has a generated public and private key.

    The passed platform will be the vip-address of the agent and the
     identity will be set.  If the identity is set to None then a random
     identity will be created.
    """

    keys = KeyStore(os.path.join(platform.volttron_home, identity + '.keys'))
    keys.generate()
    agent = platform.build_agent(identity=identity,
                                 serverkey=platform.publickey,
                                 publickey=keys.public(),
                                 secretkey=keys.secret())
    # Make publickey easily accessible for these tests
    agent.publickey = keys.public()
    gevent.sleep(0.1)  # switch context for a bit

    return agent
コード例 #6
0
ファイル: build_agent.py プロジェクト: cbs-iiith/volttron
def build_agent_with_key(platform, identity=None):
    """Create an agent instance that has a generated public and private key.

    The passed platform will be the vip-address of the agent and the
     identity will be set.  If the identity is set to None then a random
     identity will be created.
    """

    keys = KeyStore(os.path.join(platform.volttron_home,
                                          identity + '.keys'))
    keys.generate()
    agent = platform.build_agent(identity=identity,
                                  serverkey=platform.publickey,
                                  publickey=keys.public(),
                                  secretkey=keys.secret())
    # Make publickey easily accessible for these tests
    agent.publickey = keys.public()
    gevent.sleep(0.1) # switch context for a bit

    return agent
コード例 #7
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
コード例 #8
0
ファイル: core.py プロジェクト: kmorri09/openevse_volttron
 def _get_keys_from_keystore(self):
     '''Returns agent's public and secret key from keystore'''
     if self.agent_uuid:
         # this is an installed agent
         keystore_dir = os.curdir
     elif self.identity:
         if not self.volttron_home:
             raise ValueError('VOLTTRON_HOME must be specified.')
         keystore_dir = os.path.join(self.volttron_home, 'keystores',
                                     self.identity)
         if not os.path.exists(keystore_dir):
             os.makedirs(keystore_dir)
     else:
         # the agent is not installed and its identity was not set
         return None, None
     keystore_path = os.path.join(keystore_dir, 'keystore.json')
     keystore = KeyStore(keystore_path)
     return keystore.public(), keystore.secret()
コード例 #9
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
コード例 #10
0
ファイル: core.py プロジェクト: cbs-iiith/volttron
 def _get_keys_from_keystore(self):
     '''Returns agent's public and secret key from keystore'''
     if self.agent_uuid:
         # this is an installed agent
         keystore_dir = os.curdir
     elif self.identity:
         if not os.environ.get('VOLTTRON_HOME'):
             raise ValueError('VOLTTRON_HOME must be specified.')
         keystore_dir = os.path.join(
                 os.environ.get('VOLTTRON_HOME'), 'keystores',
                 self.identity)
         if not os.path.exists(keystore_dir):
             os.makedirs(keystore_dir)
     else:
         # the agent is not installed and its identity was not set
         return None, None
     keystore_path = os.path.join(keystore_dir, 'keystore.json')
     keystore = KeyStore(keystore_path)
     return keystore.public(), keystore.secret()
コード例 #11
0
def update_curve_key(curve_key_path, no_warn=False):
    try:
        with open(curve_key_path, 'r') as curve_file:
            public, secret = read_curve_key(curve_file)
    except IOError as e:
        print e
        return

    keystore_path = os.path.join(os.path.dirname(curve_key_path), 'keystore')
    
    if os.path.exists(keystore_path) and not no_warn:
        response = raw_input("{} already exists. "
                "Overwrite? [y/N]: ".format(keystore_path))
        if not response.lower().startswith('y'):
            print "Key update aborted."
            return

    keystore = KeyStore(keystore_path)
    keystore.public = public
    keystore.secret = secret
    print "Keys from {} have been transfered to {}".format(curve_key_path, 
            keystore.filename)
コード例 #12
0
def update_curve_key(curve_key_path, no_warn=False):
    try:
        with open(curve_key_path, 'r') as curve_file:
            public, secret = read_curve_key(curve_file)
    except IOError as e:
        print e
        return

    keystore_path = os.path.join(os.path.dirname(curve_key_path), 'keystore')
    
    if os.path.exists(keystore_path) and not no_warn:
        response = raw_input("{} already exists. "
                "Overwrite? [y/N]: ".format(keystore_path))
        if not response.lower().startswith('y'):
            print "Key update aborted."
            return

    keystore = KeyStore(keystore_path)
    keystore.public = public
    keystore.secret = secret
    print "Keys from {} have been transfered to {}".format(curve_key_path, 
            keystore.filename)
コード例 #13
0
import os
import sys

import gevent

from volttron.platform import get_address
from volttron.platform.agent.known_identities import VOLTTRON_CENTRAL_PLATFORM
from volttron.platform.keystore import KeyStore
from volttron.platform.messaging import topics
from volttron.platform.vip.agent import Agent


keystore = KeyStore()
agent = Agent(address=get_address(), identity="blahagent",
              publickey=keystore.public(), secretkey=keystore.secret(),
              enable_store=False)

event = gevent.event.Event()
config_store_task = gevent.spawn(agent.core.run, event)
event.wait()
del event

if VOLTTRON_CENTRAL_PLATFORM not in agent.vip.peerlist().get():
    agent.core.stop()
    print('no vcp availablel')
    sys.exit()


def receive_platform_data(peer, sender, bus, topic, headers, message):
    #assert 'message' in kwargs
コード例 #14
0
def get_new_keypair():
    tf = tempfile.NamedTemporaryFile()
    ks = KeyStore(tf.name)
    ks.generate()
    return ks.public(), ks.secret()
コード例 #15
0
class PlatformWrapper:
    def __init__(self):
        """ Initializes a new VOLTTRON instance

        Creates a temporary VOLTTRON_HOME directory with a packaged directory
        for agents that are built.
        """

        self.volttron_home = tempfile.mkdtemp()
        self.packaged_dir = os.path.join(self.volttron_home, "packaged")
        os.makedirs(self.packaged_dir)

        # in the context of this platform it is very important not to
        # use the main os.environ for anything.
        self.env = {
            'VOLTTRON_HOME': self.volttron_home,
            'PACKAGED_DIR': self.packaged_dir,
            'DEBUG_MODE': os.environ.get('DEBUG_MODE', ''),
            'DEBUG': os.environ.get('DEBUG', ''),
            'PATH': VOLTTRON_ROOT + ':' + os.environ['PATH']
        }

        # By default no web server should be started.
        self.bind_web_address = None
        self.discovery_address = None
        self.jsonrpc_endpoint = None
        self.volttron_central_address = None
        self.instance_name = None
        self.serverkey = None

        self.p_process = None
        self.t_process = None

        self.started_agent_pids = []
        self.local_vip_address = None
        self.vip_address = None
        self.encrypt = False
        self.logit('Creating platform wrapper')

        # This was used when we are testing the SMAP historian.
        self.use_twistd = False

        # Added restricted code properties
        self.certsobj = None

        # Control whether the instance directory is cleaned up when shutdown.
        # if the environment variable DEBUG is set to a True value then the
        # instance is not cleaned up.
        self.skip_cleanup = False

        # This is used as command line entry replacement.  Especially working
        # with older 2.0 agents.
        self.opts = None

        keystorefile = os.path.join(self.volttron_home, 'keystore')
        self.keystore = KeyStore(keystorefile)
        self.keystore.generate()

    def logit(self, message):
        print('{}: {}'.format(self.volttron_home, message))

    def allow_all_connections(self):
        """ Add a /.*/ entry to the auth.json file.
        """
        entry = AuthEntry(credentials="/.*/")
        authfile = AuthFile(self.volttron_home + "/auth.json")
        authfile.add(entry)

    def build_connection(self,
                         peer=None,
                         address=None,
                         identity=None,
                         publickey=None,
                         secretkey=None,
                         serverkey=None,
                         **kwargs):

        if self.encrypt:
            self.allow_all_connections()

        if address is None:
            address = self.vip_address
            serverkey = self.serverkey

        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()
        if self.encrypt:
            conn = Connection(address=address,
                              peer=peer,
                              publickey=publickey,
                              secretkey=secretkey,
                              serverkey=serverkey,
                              volttron_home=self.volttron_home)
        else:
            conn = Connection(address=self.local_vip_address,
                              peer=peer,
                              volttron_home=self.volttron_home)
        return conn

    def build_agent(self,
                    address=None,
                    should_spawn=True,
                    identity=None,
                    publickey=None,
                    secretkey=None,
                    serverkey=None,
                    agent_class=Agent,
                    **kwargs):
        """ Build an agent connnected to the passed bus.

        By default the current instance that this class wraps will be the
        vip address of the agent.

        :param address:
        :param should_spawn:
        :param identity:
        :param publickey:
        :param secretkey:
        :param serverkey:
        :param agent_class: Agent class to build
        :return:
        """
        self.logit("Building generic agent.")

        use_ipc = kwargs.pop('use_ipc', False)
        if self.encrypt:
            if serverkey is None:
                serverkey = self.serverkey
            if publickey 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()

        if address is None:
            if not self.encrypt:
                self.logit('Using IPC vip-address')
                address = "ipc://@" + self.volttron_home + "/run/vip.socket"
            else:
                self.logit('Using vip-address ' + self.vip_address)
                address = self.vip_address

        if publickey and not serverkey:
            self.logit('using instance serverkey: {}'.format(self.publickey))
            serverkey = self.publickey

        agent = agent_class(address=address,
                            identity=identity,
                            publickey=publickey,
                            secretkey=secretkey,
                            serverkey=serverkey,
                            volttron_home=self.volttron_home,
                            **kwargs)
        self.logit('platformwrapper.build_agent.address: {}'.format(address))

        # Automatically add agent's credentials to auth.json file
        if publickey:
            self.logit('Adding publickey to auth.json')
            gevent.spawn(self._append_allow_curve_key, publickey)
            gevent.sleep(0.1)

        if should_spawn:
            self.logit('platformwrapper.build_agent spawning')
            event = gevent.event.Event()
            gevent.spawn(agent.core.run, event)  #.join(0)
            event.wait(timeout=2)

            hello = agent.vip.hello().get(timeout=.3)
            self.logit('Got hello response {}'.format(hello))
        agent.publickey = publickey
        return agent

    def _read_auth_file(self):
        auth_path = os.path.join(self.volttron_home, 'auth.json')
        try:
            with open(auth_path, 'r') as fd:
                data = strip_comments(FileObject(fd, close=False).read())
                if data:
                    auth = jsonapi.loads(data)
                else:
                    auth = {}
        except IOError:
            auth = {}
        if not 'allow' in auth:
            auth['allow'] = []
        return auth, auth_path

    def _append_allow_curve_key(self, publickey):
        entry = AuthEntry(credentials=publickey)
        authfile = AuthFile(self.volttron_home + "/auth.json")
        authfile.add(entry)

    def add_vc(self):
        return add_vc_to_instance(self)

    def add_capabilities(self, publickey, capabilities):
        if isinstance(capabilities, basestring):
            capabilities = [capabilities]
        auth, auth_path = self._read_auth_file()
        cred = publickey
        allow = auth['allow']
        entry = next((item for item in allow if item['credentials'] == cred),
                     {})
        caps = entry.get('capabilities', [])
        entry['capabilities'] = list(set(caps + capabilities))

        with open(auth_path, 'w+') as fd:
            json.dump(auth, fd)

    def set_auth_dict(self, auth_dict):
        if auth_dict:
            with open(os.path.join(self.volttron_home, 'auth.json'),
                      'w') as fd:
                fd.write(json.dumps(auth_dict))

    def startup_platform(self,
                         vip_address,
                         auth_dict=None,
                         use_twistd=False,
                         mode=UNRESTRICTED,
                         encrypt=False,
                         bind_web_address=None,
                         volttron_central_address=None,
                         volttron_central_serverkey=None):

        # if not isinstance(vip_address, list):
        #     self.vip_address = [vip_address]
        # else:
        #     self.vip_address = vip_address

        self.vip_address = vip_address
        self.encrypt = encrypt
        self.mode = mode
        self.bind_web_address = bind_web_address
        if self.bind_web_address:
            self.discovery_address = "{}/discovery/".format(
                self.bind_web_address)

            # Only available if vc is installed!
            self.jsonrpc_endpoint = "{}/jsonrpc".format(self.bind_web_address)

        enable_logging = self.env.get('ENABLE_LOGGING', False)
        debug_mode = self.env.get('DEBUG_MODE', False)
        if not debug_mode:
            debug_mode = self.env.get('DEBUG', False)
        self.skip_cleanup = self.env.get('SKIP_CLEANUP', False)
        if debug_mode:
            self.skip_cleanup = True
            enable_logging = True
        self.logit("In start up platform enable_logging is {} ".format(
            enable_logging))
        assert self.mode in MODES, 'Invalid platform mode set: ' + str(mode)
        opts = None

        # see main.py for how we handle pub sub addresses.
        ipc = 'ipc://{}{}/run/'.format(
            '@' if sys.platform.startswith('linux') else '',
            self.volttron_home)
        self.local_vip_address = ipc + 'vip.socket'
        self.set_auth_dict(auth_dict)

        self.opts = {
            'verify_agents': False,
            'volttron_home': self.volttron_home,
            'vip_address': vip_address,
            'vip_local_address': ipc + 'vip.socket',
            'publish_address': ipc + 'publish',
            'subscribe_address': ipc + 'subscribe',
            'bind_web_address': bind_web_address,
            'volttron_central_address': volttron_central_address,
            'volttron_central_serverkey': volttron_central_serverkey,
            'platform_name': None,
            'developer_mode': not encrypt,
            'log': os.path.join(self.volttron_home, 'volttron.log'),
            'log_config': None,
            'monitor': True,
            'autostart': True,
            'log_level': logging.DEBUG,
            'verboseness': logging.DEBUG
        }

        pconfig = os.path.join(self.volttron_home, 'config')
        config = {}

        # Set up the configuration file based upon the passed parameters.
        parser = configparser.ConfigParser()
        parser.add_section('volttron')
        parser.set('volttron', 'vip-address', vip_address)
        if bind_web_address:
            parser.set('volttron', 'bind-web-address', bind_web_address)
        if volttron_central_address:
            parser.set('volttron', 'volttron-central-address',
                       volttron_central_address)

        if self.mode == UNRESTRICTED:
            # TODO Restricted code should set with volttron as contianer
            # if RESTRICTED_AVAILABLE:
            #     config['mobility'] = False
            #     config['resource-monitor'] = False
            #     config['verify'] = False
            with closing(open(pconfig, 'wb')) as cfg:
                cfg.write(PLATFORM_CONFIG_UNRESTRICTED.format(**config))
                parser.write(cfg)

        elif self.mode == RESTRICTED:
            if not RESTRICTED_AVAILABLE:
                raise ValueError("restricted is not available.")

            certsdir = os.path.join(self.volttron_home, 'certificates')

            print("certsdir", certsdir)
            self.certsobj = certs.Certs(certsdir)

            with closing(open(pconfig, 'wb')) as cfg:
                cfg.write(PLATFORM_CONFIG_RESTRICTED.format(**config))
            # opts = type('Options', (), {'resource-monitor':False,
            #                             'verify_agents': True,
            #                             'volttron_home': self.volttron_home})()
        else:
            raise PlatformWrapperError(
                "Invalid platform mode specified: {}".format(mode))

        log = os.path.join(self.volttron_home, 'volttron.log')
        if enable_logging:
            cmd = ['volttron', '-vv', '-l{}'.format(log)]
        else:
            cmd = ['volttron', '-l{}'.format(log)]

        if not encrypt:
            cmd.append('--developer-mode')
        print('process environment: {}'.format(self.env))
        print('popen params: {}'.format(cmd))
        self.p_process = Popen(cmd,
                               env=self.env,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)

        assert self.p_process is not None
        # A None value means that the process is still running.
        # A negative means that the process exited with an error.
        assert self.p_process.poll() is None

        self.serverkey = self.keystore.public()
        assert self.serverkey
        agent = self.build_agent()

        has_control = False
        times = 0
        while not has_control and times < 10:
            times += 1
            try:
                has_control = agent.vip.peerlist().get(timeout=.2)
            except gevent.Timeout:
                pass

        if not has_control:
            self.shutdown_platform()
            raise "Couldn't connect to core platform!"

        if bind_web_address:
            times = 0
            has_discovery = False
            while times < 10:
                times += 1
                try:
                    resp = requests.get(self.discovery_address)
                    if resp.ok:
                        has_discovery = True
                        break
                except Exception as e:
                    gevent.sleep(0.1)
                    self.logit("Connection error found {}".format(e))
            if not has_discovery:
                raise "Couldn't connect to discovery platform."

        self.use_twistd = use_twistd

        # TODO: Revise this to start twistd with platform.
        if self.use_twistd:
            tconfig = os.path.join(self.volttron_home,
                                   TMP_SMAP_CONFIG_FILENAME)

            with closing(open(tconfig, 'w')) as cfg:
                cfg.write(TWISTED_CONFIG.format(**config))

            tparams = [TWISTED_START, "-n", "smap", tconfig]
            self.t_process = subprocess.Popen(tparams, env=self.env)
            time.sleep(5)
            #self.t_process = subprocess.Popen(["twistd", "-n", "smap", "test-smap.ini"])

    def is_running(self):
        self.logit("PROCESS IS RUNNING: {}".format(self.p_process))
        return self.p_process is not None and self.p_process.poll() is None

    def twistd_is_running(self):
        return self.t_process is not None

    # def publish(self, topic, data):
    #     '''Publish data to a zmq context.
    #
    #     The publisher is goint to use the platform that is contained within
    #     this wrapper to write data to.
    #     '''
    #     if not self.zmq_context:
    #         self.zmq_context = zmq.Context()
    #     self.logit("binding publisher to: ", self.env['AGENT_PUB_ADDR'])
    #     pub = zmq.Socket(self.zmq_context, zmq.PUB)
    #     pub.bind(self.env['AGENT_PUB_ADDR'])
    #     pub.send_multipart([topic, data])

    # def fillout_file(self, filename, template, config_file):
    #
    #     try:
    #         config = json.loads(open(config_file, 'r').read())
    #     except Exception as e:
    #         sys.stderr.write (str(e))
    #         raise PlatformWrapperError("Could not load configuration file for tests")
    #
    #     config['tmpdir'] = self.tmpdir
    #
    #     outfile = os.path.join(self.tmpdir, filename)
    #     with closing(open(outfile, 'w')) as cfg:
    #         cfg.write(template.format(**config))
    #
    #     return outfile

    def direct_sign_agentpackage_creator(self, package):
        assert (RESTRICTED), "Auth not available"
        print("wrapper.certsobj", self.certsobj.cert_dir)
        assert (auth.sign_as_creator(
            package, 'creator',
            certsobj=self.certsobj)), "Signing as {} failed.".format('creator')

    def direct_sign_agentpackage_admin(self, package):
        assert (RESTRICTED), "Auth not available"
        assert (auth.sign_as_admin(
            package, 'admin',
            certsobj=self.certsobj)), "Signing as {} failed.".format('admin')

    def direct_sign_agentpackage_initiator(self, package, config_file,
                                           contract):
        assert (RESTRICTED), "Auth not available"
        files = {"config_file": config_file, "contract": contract}
        assert (auth.sign_as_initiator(package,
                                       'initiator',
                                       files=files,
                                       certsobj=self.certsobj)
                ), "Signing as {} failed.".format('initiator')

    def _aip(self):
        opts = type('Options', (), self.opts)
        aip = AIPplatform(opts)
        aip.setup()
        return aip

    # TODO Remove when verified that the other method works properly.
    # def _install_agent(self, wheel_file, start, vip_identity):
    #     aip = self._aip()
    #     auuid = aip.install_agent(wheel_file, vip_identity=vip_identity)
    #     assert auuid is not None
    #     if start:
    #         self.logit('STARTING: {}'.format(wheel_file))
    #         status = self.start_agent(auuid)
    #         # aip.start_agent(auuid)
    #         # status = aip.agent_status(auuid)
    #         self.logit('STATUS NOW: {}'.format(status))
    #         assert status > 0
    #
    #     return auuid

    def _install_agent(self, wheel_file, start, vip_identity):

        agent = self.build_agent()
        self.logit('Creating channel for sending the agent.')
        channel_name = str(uuid.uuid4())
        channel = agent.vip.channel('control', channel_name)
        gevent.sleep(0.3)
        self.logit('calling control install agent.')
        result = agent.vip.rpc.call('control', 'install_agent', wheel_file,
                                    channel_name, vip_identity)
        self.logit('waiting for ready')
        response = channel.recv()
        if response != b'ready':
            raise ValueError(
                'Invalid channel protocol returned {}'.format(response))

        with open(wheel_file, 'rb') as fin:
            _log.debug('sending wheel to control.')
            while True:
                data = fin.read(8125)
                if not data:
                    _log.debug('Finished sending data')
                    break
                channel.send(data)

        _log.debug('sending done message.')
        channel.send('done')
        try:
            # must do this before channel closes or process will hang.
            auuid = result.get(timeout=10)
            _log.debug('closing channel')
        except gevent.Timeout:
            _log.error('Timeout in channel')
        finally:
            channel.close(linger=0)
            del channel

        if start:
            self.start_agent(auuid)

        return auuid

    def install_multiple_agents(self, agent_configs):
        """
        Installs mutltiple agents on the platform.

        :param agent_configs:list
            A list of 3-tuple that allows the configuration of a platform
            in a single go.  The tuple order is
            1. path to the agent directory.
            2. configuration data (either file or json data)
            3. Whether the agent should be started or not.

        :return:list:
            A list of uuid's associated with the agents that were installed.


        :Note:
            In order for this method to be called the platform must be
            currently running.
        """
        if not self.is_running():
            raise PlatformWrapperError("Instance isn't running!")
        results = []

        for path, config, start in agent_configs:
            results = self.install_agent(agent_dir=path,
                                         config_file=config,
                                         start=start)

        return results

    def install_agent(self,
                      agent_wheel=None,
                      agent_dir=None,
                      config_file=None,
                      start=True,
                      vip_identity=None):
        """ Install and optionally start an agent on the instance.

            This function allows installation from an agent wheel or an
            agent directory (NOT BOTH).  If an agent_wheel is specified then
            it is assumed to be ready for installation (has a config file).
            If an agent_dir is specified then a config_file file must be
            specified or if it is not specified then it is assumed that the
            file agent_dir/config is to be used as the configuration file.  If
            none of these exist then an assertion error will be thrown.

            This function will return with a uuid of the installed agent.
        :param agent_wheel:
        :param agent_dir:
        :param config_file:
        :param start:
        :param vip_identity:
        :return:
        """

        assert self.is_running(), "Instance must be running to install agent."
        assert agent_wheel or agent_dir, "Invalid agent_wheel or agent_dir."

        if agent_wheel:
            assert not agent_dir
            assert not config_file
            assert os.path.exists(agent_wheel)
            wheel_file = agent_wheel

        if agent_dir:
            assert not agent_wheel
            if isinstance(config_file, dict):
                from os.path import join, basename
                temp_config = join(self.volttron_home,
                                   basename(agent_dir) + "_config_file")
                with open(temp_config, "w") as fp:
                    fp.write(json.dumps(config_file))
                config_file = temp_config
            elif not config_file:
                assert os.path.exists(os.path.join(agent_dir, "config"))
                config_file = os.path.join(agent_dir, "config")
            elif os.path.exists(config_file):
                pass  # config_file already set!
            else:
                raise ValueError("Can't determine correct config file.")

            self.logit('Building agent package')
            wheel_file = self.build_agentpackage(agent_dir, config_file)
            assert wheel_file

        agent_uuid = self._install_agent(wheel_file, start, vip_identity)

        assert agent_uuid is not None

        if start:
            assert self.is_agent_running(agent_uuid)

        return agent_uuid

    def start_agent(self, agent_uuid):
        self.logit('Starting agent {}'.format(agent_uuid))
        self.logit("VOLTTRON_HOME SETTING: {}".format(
            self.env['VOLTTRON_HOME']))
        cmd = ['volttron-ctl', 'start', agent_uuid]
        p = Popen(cmd, env=self.env, stdout=sys.stdout, stderr=sys.stderr)
        p.wait()

        # Confirm agent running
        cmd = ['volttron-ctl', 'status', agent_uuid]
        res = subprocess.check_output(cmd, env=self.env)
        self.logit("Subprocess res is {}".format(res))
        assert 'running' in res
        pidpos = res.index('[') + 1
        pidend = res.index(']')
        pid = int(res[pidpos:pidend])

        self.started_agent_pids.append(pid)
        return int(pid)

    def stop_agent(self, agent_uuid):
        # Confirm agent running
        _log.debug("STOPPING AGENT: {}".format(agent_uuid))
        try:
            cmd = ['volttron-ctl', 'stop', agent_uuid]
            res = subprocess.check_output(cmd, env=self.env)
        except CalledProcessError as ex:
            _log.error("Exception: {}".format(ex))
        return self.agent_status(agent_uuid)

    def list_agents(self):
        agent = self.build_agent()
        print('PEER LIST: {}'.format(agent.vip.peerlist().get(timeout=10)))
        agent_list = agent.vip.rpc('control', 'list_agents').get(timeout=10)
        agent.core.stop(timeout=3)
        return agent_list

    def remove_agent(self, agent_uuid):
        """Remove the agent specified by agent_uuid"""
        _log.debug("REMOVING AGENT: {}".format(agent_uuid))
        try:
            cmd = ['volttron-ctl', 'remove', agent_uuid]
            res = subprocess.check_output(cmd, env=self.env)
        except CalledProcessError as ex:
            _log.error("Exception: {}".format(ex))
        return self.agent_status(agent_uuid)

    def is_agent_running(self, agent_uuid):
        return self.agent_status(agent_uuid) is not None

    def agent_status(self, agent_uuid):
        _log.debug("AGENT_STATUS: {}".format(agent_uuid))
        # Confirm agent running
        cmd = ['volttron-ctl', 'status', agent_uuid]
        pid = None
        try:
            res = subprocess.check_output(cmd, env=self.env)

            try:
                pidpos = res.index('[') + 1
                pidend = res.index(']')
                pid = int(res[pidpos:pidend])
            except:
                pid = None
        except CalledProcessError as ex:
            _log.error("Exception: {}".format(ex))

        return pid

    def build_agentpackage(self, agent_dir, config_file):
        assert os.path.exists(agent_dir)
        assert os.path.exists(config_file)
        wheel_path = packaging.create_package(agent_dir, self.packaged_dir)
        packaging.add_files_to_package(
            wheel_path, {'config_file': os.path.join('./', config_file)})

        return wheel_path

    # def direct_build_agentpackage(self, agent_dir):
    #     self.logit("Building agent_directory ", agent_dir)
    #     wheel_path = packaging.create_package(os.path.join('./', agent_dir),
    #                                           self.packaged_dir)
    #
    #     return wheel_path
    #
    # def direct_send_agent(self, package, target):
    #     pparams = [VCTRL, SEND_AGENT, target, package]
    #     print (pparams, "CWD", os.getcwd())
    #     send_process = subprocess.call(pparams, env=self.env)
    #     print ("Done sending to", target)
    #
    # def direct_configure_agentpackage(self, agent_wheel, config_file):
    #     packaging.add_files_to_package(agent_wheel, {
    #                             'config_file':os.path.join('./', config_file)
    #                         })
    #
    #


#     def direct_build_install_agent(self, agent_dir, config_file):
#         agent_wheel = self.build_agentpackage(agent_dir=agent_dir,
#             config_file=config_file)
#         self.direct_configure_agentpackage(agent_wheel, config_file)
#         assert(agent_wheel is not None,"Agent wheel was not built")
#
#         uuid = self.test_aip.install_agent(agent_wheel)
#         #aip volttron_home, verify_agents
#         return uuid
# #         conn.call.start_agent()

# def direct_build_install_run_agent(self, agent_dir, config_file):
#     agent_uuid = self.direct_build_install_agent(agent_dir, config_file)
#     self.direct_start_agent(agent_uuid)
#     return agent_uuid
#
# def direct_build_send_agent(self, agent_dir, config_file, target):
#     agent_uuid = self.direct_buid_install_agent(agent_dir, config_file)
#     self.direct_start_agent(agent_uuid)
#     return agent_uuid

    def confirm_agent_running(self,
                              agent_name,
                              max_retries=5,
                              timeout_seconds=2):
        running = False
        retries = 0
        while not running and retries < max_retries:
            status = self.test_aip.status_agents()
            print("Status", status)
            if len(status) > 0:
                status_name = status[0][1]
                assert status_name == agent_name

                assert len(
                    status[0][2]) == 2, 'Unexpected agent status message'
                status_agent_status = status[0][2][1]
                running = not isinstance(status_agent_status, int)
            retries += 1
            time.sleep(timeout_seconds)
        return running

    # def direct_stop_agent(self, agent_uuid):
    #     result = self.conn.call.stop_agent(agent_uuid)
    #     print result

    def shutdown_platform(self):
        '''Stop platform here

           This function will shutdown the platform and attempt to kill any
           process that the platformwrapper has started.
        '''
        import signal
        self.logit('shutting down platform: PIDS: {}'.format(
            self.started_agent_pids))
        while self.started_agent_pids:
            pid = self.started_agent_pids.pop()
            self.logit('ending pid: {}'.format(pid))
            try:
                os.kill(pid, signal.SIGTERM)
            except:
                self.logit('could not kill: {} '.format(pid))

        if self.p_process is not None:
            try:
                gevent.sleep(0.2)
                self.p_process.terminate()
                gevent.sleep(0.2)
            except OSError:
                self.logit('Platform process was terminated.')
        else:
            self.logit("platform process was null")

        if self.use_twistd and self.t_process != None:
            self.t_process.kill()
            self.t_process.wait()
        elif self.use_twistd:
            self.logit("twistd process was null")
        if not self.skip_cleanup:
            self.logit('Removing {}'.format(self.volttron_home))
            shutil.rmtree(self.volttron_home, ignore_errors=True)
コード例 #16
0
def get_new_keypair():
    tf = tempfile.NamedTemporaryFile()
    ks = KeyStore(tf.name)
    ks.generate()
    return ks.public(), ks.secret()
コード例 #17
0
ファイル: platformwrapper.py プロジェクト: miraabid/bemoss
    def build_agent(self,
                    address=None,
                    should_spawn=True,
                    identity=None,
                    publickey=None,
                    secretkey=None,
                    serverkey=None,
                    generatekeys=False,
                    **kwargs):
        """ Build an agent connnected to the passed bus.

        By default the current instance that this class wraps will be the
        vip address of the agent.

        :param address:
        :param should_spawn:
        :param identity:
        :param publickey:
        :param secretkey:
        :param serverkey:
        :return:
        """
        self.logit("Building generic agent.")

        use_ipc = kwargs.pop('use_ipc', False)
        if address is None:
            if use_ipc:
                self.logit('Using IPC vip-address')
                address = "ipc://@" + self.volttron_home + "/run/vip.socket"
            else:
                self.logit('Using vip-address ' + self.vip_address)
                address = self.vip_address

        if generatekeys:
            self.logit('generating new public secret key pair')
            tf = tempfile.NamedTemporaryFile()
            ks = KeyStore(tf.name)
            ks.generate()
            publickey = ks.public()
            secretkey = ks.secret()

        if publickey and not serverkey:
            self.logit('using instance serverkey: {}'.format(self.publickey))
            serverkey = self.publickey

        agent = Agent(address=address,
                      identity=identity,
                      publickey=publickey,
                      secretkey=secretkey,
                      serverkey=serverkey,
                      **kwargs)
        self.logit('platformwrapper.build_agent.address: {}'.format(address))

        # Automatically add agent's credentials to auth.json file
        if publickey:
            self.logit('Adding publickey to auth.json')
            gevent.spawn(self._append_allow_curve_key, publickey)
            gevent.sleep(0.1)

        if should_spawn:
            self.logit('platformwrapper.build_agent spawning')
            event = gevent.event.Event()
            gevent.spawn(agent.core.run, event)  #.join(0)
            event.wait(timeout=2)

            hello = agent.vip.hello().get(timeout=.3)
            self.logit('Got hello response {}'.format(hello))

        return agent