예제 #1
0
파일: aip.py 프로젝트: tpktang/volttron
    def set_agent_user_permissions(self, volttron_agent_user,
                                   agent_uuid, agent_dir):
        name = self.agent_name(agent_uuid)
        agent_path_with_name = os.path.join(agent_dir, name)
        # Directories in the install path have read/execute
        # except agent-data dir. agent-data dir has rwx
        self.set_acl_for_path("rx", volttron_agent_user, agent_dir)
        # creates dir if it doesn't exist
        data_dir = self._get_agent_data_dir(agent_path_with_name)

        for (root, directories, files) in os.walk(agent_dir, topdown=True):
            for directory in directories:
                if directory == os.path.basename(data_dir):
                    self.set_acl_for_path("rwx", volttron_agent_user,
                                          os.path.join(root, directory))
                else:
                    self.set_acl_for_path("rx", volttron_agent_user,
                                          os.path.join(root, directory))
        # In install directory, make all files' permissions to 400.
        # Then do setfacl -m "r" to only agent user
        self._set_agent_dir_file_permissions(agent_dir, volttron_agent_user, data_dir)

        # if messagebus is rmq.
        # TODO: For now provide read access to all agents since this is used for
        #  multi instance connections. This will not be requirement in
        #  VOLTTRON 8.0 once CSR is implemented for
        #  federation and shovel. The below lines can be removed then
        if self.message_bus == 'rmq':
            os.chmod(os.path.join(get_home(), "certificates/private"), 0o755)
            self.set_acl_for_path("r", volttron_agent_user,
                                  os.path.join(get_home(), "certificates/private", self.instance_name + "-admin.pem"))
예제 #2
0
    def __init__(self, filetowatch, callback):
        # Protect from circular reference for file
        from volttron.platform import get_home

        super(VolttronHomeFileReloader, self).__init__([get_home() + '/' + filetowatch])
        _log.debug("patterns is {}".format([get_home() + '/' + filetowatch]))
        self._callback = callback
예제 #3
0
파일: utils.py 프로젝트: VOLTTRON/volttron
def watch_file(fullpath, callback):
    """Run callback method whenever the file changes

        Not available on OS X/MacOS.
    """

    dirname, filename = os.path.split(fullpath)
    _log.info("Adding file watch for %s dirname=%s, filename=%s", fullpath,
              get_home(), filename)
    observer = Observer()
    observer.schedule(VolttronHomeFileReloader(filename, callback),
                      path=get_home())
    observer.start()
    _log.info("Added file watch for %s", fullpath)
예제 #4
0
def get_aip():
    """Get AIPplatform to interface with agent directories in vhome"""

    vhome = get_home()
    options = type("Options", (), dict(volttron_home=vhome))
    aip = AIPplatform(options)
    return aip
예제 #5
0
    def __init__(self):
        self.instance_name = get_platform_instance_name()
        # This is written durn the bootstrap phase of the rabbitmq installation
        # however for docker we don't write this at all so we need to
        # use the default location for this
        rmq_home_file = os.path.expanduser("~/.volttron_rmq_home")
        if os.path.isfile(rmq_home_file):
            with open(os.path.expanduser("~/.volttron_rmq_home")) as f:
                self.rabbitmq_server = f.read().strip()
        else:
            self.rabbitmq_server = os.path.expanduser(
                "~/rabbitmq_server/rabbitmq_server-3.7.7/")

        assert os.path.isdir(self.rabbitmq_server
                             ), "Missing rabbitmq server directory{}".format(
                                 self.rabbitmq_server)
        self.crts = certs.Certs()
        self.volttron_home = get_home()
        self.volttron_rmq_config = os.path.join(self.volttron_home,
                                                'rabbitmq_config.yml')
        self.default_pass = "******"
        self.config_opts = None
        try:
            self.load_rmq_config()
        except (IOError, yaml.YAMLError) as exc:
            self.config_opts = {}
        self._set_default_config()
예제 #6
0
    def __init__(self, address, peer=None, publickey=None,
                 secretkey=None, serverkey=None, volttron_home=None, **kwargs):

        self._log = logging.getLogger(__name__)
        self._log.debug("Connection: {}, {}, {}, {}, {}"
                   .format(address, peer, publickey, secretkey, serverkey))
        self._address = address
        self._peer = peer
        self._serverkey = None
        if peer is None:
            self._log.warn('Peer is non so must be passed in call method.')
        self.volttron_home = volttron_home

        if self.volttron_home is None:
            self.volttron_home = os.path.abspath(platform.get_home())

        if address.startswith('ipc'):
            full_address = address
        else:
            parsed = urlparse.urlparse(address)
            if parsed.scheme == 'tcp':
                qs = urlparse.parse_qs(parsed.query)
                self._log.debug('QS IS: {}'.format(qs))
                if 'serverkey' in qs:
                    self._serverkey = qs.get('serverkey')
                else:
                    self._serverkey = serverkey

                # Handle case when the address has all the information in it.
                if 'serverkey' in qs.keys() and 'publickey' in qs.keys() and \
                                'secretkey' in qs.keys():
                    full_address = address
                else:
                    full_address = build_vip_address_string(
                        vip_root=address, serverkey=serverkey,
                        publickey=publickey, secretkey=secretkey
                    )
            elif parsed.scheme == 'ipc':
                full_address = address
            else:
                raise AttributeError(
                    'Invalid address type specified. ipc or tcp accepted.')

        self._server = Agent(address=full_address,
                             volttron_home=self.volttron_home,
                             enable_store=False,
                             reconnect_interval=1000,
                             **kwargs)
        # TODO the following should work as well, but doesn't.  Not sure why!
        # self._server = Agent(address=address, serverkey=serverkey,
        #                      secretkey=secretkey, publickey=publickey,
        #                      enable_store=False,
        #                      volttron_home=self.volttron_home, **kwargs)
        self._greenlet = None
        self._connected_since = None
        self._last_publish = None
        self._last_publish_failed = False
        self._last_rpc_call = None
        # Make the actual attempt to connect to the server.
        self.is_connected()
예제 #7
0
파일: utils.py 프로젝트: VOLTTRON/volttron
def store_message_bus_config(message_bus, instance_name):
    # If there is no config file or home directory yet, create volttron_home
    # and config file
    if not instance_name:
        raise ValueError("Instance name should be a valid string and should "
                         "be unique within a network of volttron instances "
                         "that communicate with each other. start volttron "
                         "process with '--instance-name <your instance>' if "
                         "you are running this instance for the first time. "
                         "Or add instance-name = <instance name> in "
                         "vhome/config")

    v_home = get_home()
    config_path = os.path.join(v_home, "config")
    if os.path.exists(config_path):
        config = ConfigParser()
        config.read(config_path)
        config.set('volttron', 'message-bus', message_bus)
        config.set('volttron', 'instance-name', instance_name)
        with open(config_path, 'w') as configfile:
            config.write(configfile)
    else:
        if not os.path.exists(v_home):
            os.makedirs(v_home, 0o755)
        config = ConfigParser()
        config.add_section('volttron')
        config.set('volttron', 'message-bus', message_bus)
        config.set('volttron', 'instance-name', instance_name)

        with open(config_path, 'w') as configfile:
            config.write(configfile)
        # all agents need read access to config file
        os.chmod(config_path, 0o744)
예제 #8
0
def test_file_watcher(volttron_instance, publish_agent):
    test_path = os.path.join(get_home(), "test.txt")

    with open(test_path, "w") as textfile:
        textfile.write("test_data")

    test_config = {
        "files": [
            {
                "file": test_path,
                "topic": "platform/test_topic"
            }
        ]
    }

    watcher_uuid = volttron_instance.install_agent(
        agent_dir=get_ops("FileWatchPublisher"),
        config_file=test_config,
        start=True,
        vip_identity="health_test")

    with open(test_path, "w+") as textfile:
        textfile.write("more test_data")

    gevent.sleep(1)

    assert publish_agent.callback.call_count == 1
    print(publish_agent.callback.call_args)
    volttron_instance.remove_agent(watcher_uuid)
    os.remove(test_path)
예제 #9
0
    def __init__(self,
                 address,
                 peer=None,
                 publickey=None,
                 secretkey=None,
                 serverkey=None,
                 volttron_home=None,
                 **kwargs):
        _log.debug("Connection: {}, {}, {}, {}, {}".format(
            address, peer, publickey, secretkey, serverkey))
        self._address = address
        self._peer = peer
        self._serverkey = None
        if peer is None:
            _log.warn('Peer is non so must be passed in call method.')
        self.volttron_home = volttron_home

        if self.volttron_home is None:
            self.volttron_home = os.path.abspath(platform.get_home())

        if address.startswith('ipc'):
            full_address = address
        else:
            parsed = urlparse.urlparse(address)
            if parsed.scheme == 'tcp':
                qs = urlparse.parse_qs(parsed.query)
                _log.debug('QS IS: {}'.format(qs))
                if 'serverkey' in qs:
                    self._serverkey = qs.get('serverkey')
                else:
                    self._serverkey = serverkey

                # Handle case when the address has all the information in it.
                if 'serverkey' in qs.keys() and 'publickey' in qs.keys() and \
                                'secretkey' in qs.keys():
                    full_address = address
                else:
                    full_address = build_vip_address_string(
                        vip_root=address,
                        serverkey=serverkey,
                        publickey=publickey,
                        secretkey=secretkey)
            elif parsed.scheme == 'ipc':
                full_address = address
            else:
                raise AttributeError(
                    'Invalid address type specified. ipc or tcp accepted.')
        self._server = Agent(address=full_address,
                             volttron_home=self.volttron_home,
                             enable_store=False,
                             reconnect_interval=1000,
                             **kwargs)
        self._greenlet = None
        self._connected_since = None
        self._last_publish = None
        self._last_publish_failed = False
        self._last_rpc_call = None
        # Make the actual attempt to connect to the server.
        self.is_connected()
예제 #10
0
def get_agent_user_from_dir(agent_name, agent_uuid):
    """
    :param agent_uuid:
    :return: Unix user ID if installed Volttron agent
    """
    user_id_path = os.path.join(get_home(), "agents", agent_uuid, "USER_ID")
    with open(user_id_path, 'r') as id_file:
        return id_file.readline()
예제 #11
0
    def __init__(self, ssl_private_key):

        self._ssl_private_key = ssl_private_key
        self._userdict = None
        self.reload_userdict()
        self._observer = Observer()
        self._observer.schedule(
            FileReloader("web-users.json", self.reload_userdict), get_home())
        self._observer.start()
예제 #12
0
def main():
    # parse the command line arguments
    arg_parser = argparse.ArgumentParser(description=__doc__)

    arg_parser.add_argument(
        "--address", help="Target only device(s) at <address> for request")

    arg_parser.add_argument(
        "--range",
        type=int,
        nargs=2,
        metavar=('LOW', 'HIGH'),
        help="Lower and upper limit on device ID in results")

    arg_parser.add_argument(
        "--timeout",
        type=int,
        metavar=('SECONDS'),
        help="Time, in seconds, to wait for responses. Default: %(default)s",
        default=5)

    arg_parser.add_argument("--proxy-id",
                            help="VIP IDENTITY of the BACnet proxy agent.",
                            default="platform.bacnet_proxy")

    args = arg_parser.parse_args()

    _log.debug("initialization")
    _log.debug("    - args: %r", args)

    keystore = KeyStore()
    agent = BACnetInteraction(args.proxy_id,
                              address=get_address(),
                              volttron_home=get_home(),
                              publickey=keystore.public,
                              secretkey=keystore.secret,
                              enable_store=False)

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

    kwargs = {'address': args.address}

    if args.range is not None:
        kwargs['low_device_id'] = int(args.range[0])
        kwargs['high_device_id'] = int(args.range[1])

    try:
        agent.send_iam(**kwargs)
    except errors.Unreachable:
        _log.error(
            "There is no BACnet proxy Agent running on the platform with the VIP IDENTITY {}"
            .format(args.proxy_id))
    else:
        gevent.sleep(args.timeout)
예제 #13
0
def _start_rabbitmq_without_ssl(rmq_config, conf_file, env=None):
    """
    Check if basic RabbitMQ configuration is available. Start RabbitMQ in
    non ssl mode so that we can login as guest to create volttron users,
    exchanges, and vhost.
    :return:
    """
    if not rmq_config.volttron_home:
        rmq_config.volttron_home = get_home()

    rmq_home = rmq_config.rmq_home
    if not rmq_home:
        rmq_home = os.path.join(os.path.expanduser("~"),
                                "rabbitmq_server/rabbitmq_server-3.7.7")
        if os.path.exists(rmq_home):
            os.environ['RABBITMQ_HOME'] = rmq_home
        else:
            print("\nERROR:\n"
                  "Missing key 'rmq_home' in RabbitMQ config and RabbitMQ is "
                  "not installed in default path: \n"
                  "~/rabbitmq_server/rabbitmq_server-3.7.7 \n"
                  "Please set the correct RabbitMQ installation path in "
                  "rabbitmq_config.yml")
            exit(1)
    else:
        if not os.path.exists(rmq_home) or not os.path.exists(os.path.join(
                rmq_home, 'sbin/rabbitmq-server')):
            print("\nERROR:\n"
                  "Invalid rmq-home value ({}). Please fix rmq-home "
                  "in {} and rerun this script".format(
                rmq_home, rmq_config.volttron_rmq_config))
            exit(1)
        else:
            os.environ['RABBITMQ_HOME'] = rmq_home

    # attempt to stop
    stop_rabbit(rmq_home, env, quite=True)

    if rmq_config.amqp_port != 5672 and rmq_config.mgmt_port != 15672:
        # If ports if non ssl ports are not default write a rabbitmq.conf before
        # restarting
        new_conf = """listeners.tcp.default = {}
management.listener.port = {}""".format(rmq_config.amqp_port, rmq_config.mgmt_port)

        with open(conf_file, 'w+') as r_conf:
            r_conf.write(new_conf)

    # Need to write env file even when starting without ssl mode since env file will provide the right node name,
    # tcp port and conf file to use. This is essential for tests as we don't use default port, paths or node name.
    # TODO - we should probably not use default node name even for non test use case to avoid node name class when
    #        you have more than one instance of RMQ on the same machine
    write_env_file(rmq_config, conf_file, env)

    # Start RabbitMQ server
    _log.info("Starting RabbitMQ server")
    start_rabbit(rmq_config.rmq_home, env=env)
예제 #14
0
    def __init__(self, rmq_mgmt, ssl_public_key):

        self._rmq_mgmt = rmq_mgmt
        self._ssl_public_key = ssl_public_key
        self._userdict = None
        self.reload_userdict()
        self._observer = Observer()
        self._observer.schedule(
            FileReloader("web-users.json", self.reload_userdict), get_home())
        self._observer.start()
        self._certs = Certs()
예제 #15
0
 def brute_force_platform_shutdown(self):
     for agent_uuid in self.agents.iterkeys():
         _log.debug("Stopping agent UUID {}".format(agent_uuid))
         self.stop_agent(agent_uuid)
     # kill the platform
     pid = None
     pid_file = "{vhome}/VOLTTRON_PID".format(vhome=get_home())
     with open(pid_file) as f:
         pid = int(f.read())
     if pid:
         os.kill(pid, signal.SIGINT)
         os.remove(pid_file)
예제 #16
0
파일: utils.py 프로젝트: VOLTTRON/volttron
def load_platform_config(vhome=None):
    """Loads the platform config file if the path exists."""
    config_opts = {}
    if not vhome:
        vhome = get_home()
    path = os.path.join(vhome, 'config')
    if os.path.exists(path):
        parser = ConfigParser()
        parser.read(path)
        options = parser.options('volttron')
        for option in options:
            config_opts[option] = parser.get('volttron', option)
    return config_opts
예제 #17
0
파일: agent.py 프로젝트: rlutes/volttron
    def __init__(self, config_path, **kwargs):
        super(VolttronCentralPlatform, self).__init__(**kwargs)

        self._local_instance_name = None
        self._local_instance_uuid = None
        self._local_serverkey = None
        self._local_bind_web_address = None
        self._external_addresses = None

        self._volttron_central_reconnect_interval = 5
        self._volttron_central_http_address = None
        self._volttron_central_tcp_address = None
        self._volttron_central_ipc_address = None
        self._volttron_central_serverkey = None
        self._volttron_central_publickey = None

        self._volttron_central_connection = None
        self._control_connection = None

        settings_path = os.path.join(get_home(), "data/vcp.settings")
        self._settings = load_create_store(settings_path)
        config = utils.load_config(config_path)
        self.reconfigure(**config)

        # Flag set after the platform has a guaranteed connection to the router.
        self._agent_started = False
        self._is_registering = False
        self._is_registered = False
        self._was_unmanaged = False

        self._devices = {}
        self._device_topic_hashes = {}

        self._topic_replace_map = {}

        # Default publish interval to 20 seconds.
        self._stats_publish_interval = 20
        self._stats_publisher = None
        if config.get('stats-publish-interval') is None:
            config['stats-publish-interval'] = self._stats_publish_interval
        if self._settings.get('instance-uuid'):
            config['instance-uuid'] = self._settings.get('instance-uuid')
        if config.get('volttron-central-reconnect-interval') is None:
            config['volttron-central-reconnect-interval'] = \
                self._volttron_central_reconnect_interval
        self._topic_replace_list = config.get("topic_replace_list", [])
        self.reconfigure(**config)

        # This is scheduled after first call to the reconnect function
        self._scheduled_connection_event = None
예제 #18
0
파일: utils.py 프로젝트: VOLTTRON/volttron
def vip_main(agent_class, identity=None, version='0.1', **kwargs):
    """Default main entry point implementation for VIP agents."""
    try:
        # If stdout is a pipe, re-open it line buffered
        if isapipe(sys.stdout):
            # Hold a reference to the previous file object so it doesn't
            # get garbage collected and close the underlying descriptor.
            stdout = sys.stdout
            sys.stdout = os.fdopen(stdout.fileno(), 'w', 1)

        # Quiet printing of KeyboardInterrupt by greenlets
        Hub = gevent.hub.Hub
        Hub.NOT_ERROR = Hub.NOT_ERROR + (KeyboardInterrupt, )

        config = os.environ.get('AGENT_CONFIG')
        identity = os.environ.get('AGENT_VIP_IDENTITY', identity)
        message_bus = os.environ.get('MESSAGEBUS', 'zmq')
        if identity is not None:
            if not is_valid_identity(identity):
                _log.warning('Deprecation warining')
                _log.warning(
                    'All characters in {identity} are not in the valid set.'.
                    format(idenity=identity))

        address = get_address()
        agent_uuid = os.environ.get('AGENT_UUID')
        volttron_home = get_home()

        from volttron.platform.certs import Certs
        certs = Certs()
        agent = agent_class(config_path=config,
                            identity=identity,
                            address=address,
                            agent_uuid=agent_uuid,
                            volttron_home=volttron_home,
                            version=version,
                            message_bus=message_bus,
                            **kwargs)

        try:
            run = agent.run
        except AttributeError:
            run = agent.core.run
        task = gevent.spawn(run)
        try:
            task.join()
        finally:
            task.kill()
    except KeyboardInterrupt:
        pass
예제 #19
0
    def __init__(self, certificate_dir=None):
        """Creates a Certs instance"""

        self.default_certs_dir = os.path.join(get_home(), 'certificates')
        self.root_ca_name = get_platform_instance_name() + '-root-ca'
        self.trusted_ca_name = get_platform_instance_name() + '-trusted-cas'
        self.default_root_ca_cn = '{} {}'.format(gethostname(),
                                                 self.root_ca_name)

        if not certificate_dir:
            certificate_dir = self.default_certs_dir
            # If user provided explicit directory then it should exist
            if not os.path.exists(certificate_dir):
                if certificate_dir != self.default_certs_dir:
                    raise ValueError('Invalid cert_dir {}'.format(self.cert_dir))

        self.cert_dir = os.path.join(os.path.expanduser(certificate_dir),
                                     'certs')
        self.private_dir = os.path.join(os.path.expanduser(certificate_dir),
                                        'private')
        self.ca_db_dir = os.path.join(os.path.expanduser(certificate_dir),
                                      'ca_db')
        self.csr_pending_dir = os.path.join(os.path.expanduser(certificate_dir),
                                            'pending_csr')
        self.remote_cert_dir = os.path.join(os.path.expanduser(certificate_dir),
                                            'remote_certs')
        self.certs_pending_dir = os.path.join(os.path.expanduser(certificate_dir),
                                              'pending_certs')
        self.rejected_dir = os.path.join(os.path.expanduser(certificate_dir),
                                         'rejected')

        required_paths = (self.cert_dir, self.private_dir, self.ca_db_dir,
                          self.csr_pending_dir, self.remote_cert_dir, self.certs_pending_dir)

        try:
            dir_created = False
            for p in required_paths:
                if not os.path.exists(p):
                    # explicitly provide rx to others since agent users should
                    # have read access to these dirs
                    os.makedirs(p)
                    os.chmod(p, 0o755)
                    dir_created = True
                else:
                    # if one exists all of them should exist. break
                    break
            if dir_created:
                os.chmod(os.path.expanduser(certificate_dir), 0o755)
        except Exception:
            raise RuntimeError("No permission to create certificates directory")
예제 #20
0
 def get_remote_certs_dir(self):
     if not self.remote_certs_dir:
         install_dir = os.path.join(get_home(), "agents",
                                    self._core().agent_uuid)
         files = os.listdir(install_dir)
         for f in files:
             agent_dir = os.path.join(install_dir, f)
             if os.path.isdir(agent_dir):
                 break  # found
         sub_dirs = os.listdir(agent_dir)
         for d in sub_dirs:
             d_path = os.path.join(agent_dir, d)
             if os.path.isdir(d_path) and d.endswith("agent-data"):
                 self.remote_certs_dir = d_path
     return self.remote_certs_dir
예제 #21
0
def main():
    # parse the command line arguments
    arg_parser = argparse.ArgumentParser(description=__doc__)

    arg_parser.add_argument("--address",
                            help="Target only device(s) at <address> for request")


    arg_parser.add_argument("--range", type=int, nargs=2, metavar=('LOW', 'HIGH'),
                            help="Lower and upper limit on device ID in results")

    arg_parser.add_argument("--timeout", type=int, metavar=('SECONDS'),
                            help="Time, in seconds, to wait for responses. Default: %(default)s",
                            default=5)

    arg_parser.add_argument("--proxy-id",
                            help="VIP IDENTITY of the BACnet proxy agent.",
                            default="platform.bacnet_proxy")
    
    args = arg_parser.parse_args()

    _log.debug("initialization")
    _log.debug("    - args: %r", args)

    keystore = KeyStore()
    agent = BACnetInteraction(args.proxy_id,
                              address=get_address(),
                              volttron_home=get_home(),
                              publickey=keystore.public,
                              secretkey=keystore.secret,
                              enable_store=False)

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

    kwargs = {'address': args.address}

    if args.range is not None:
        kwargs['low_device_id'] = int(args.range[0])
        kwargs['high_device_id'] = int(args.range[1])

    try:
        agent.send_iam(**kwargs)
    except errors.Unreachable:
        _log.error("There is no BACnet proxy Agent running on the platform with the VIP IDENTITY {}".format(args.proxy_id))
    else:
        gevent.sleep(args.timeout)
예제 #22
0
    def __init__(self, tls_private_key=None, web_secret_key=None):

        self._tls_private_key = tls_private_key
        self._web_secret_key = web_secret_key
        if self._tls_private_key is None and self._web_secret_key is None:
            raise ValueError("Must have either ssl_private_key or web_secret_key specified!")
        if self._tls_private_key is not None and self._web_secret_key is not None:
            raise ValueError("Must use either ssl_private_key or web_secret_key not both!")
        self._userdict = None
        self.reload_userdict()
        self._observer = Observer()
        self._observer.schedule(
            VolttronHomeFileReloader("web-users.json", self.reload_userdict),
            get_home()
        )
        self._observer.start()
예제 #23
0
def vip_main(agent_class, identity=None, version='0.1', **kwargs):
    """Default main entry point implementation for VIP agents."""
    try:
        # If stdout is a pipe, re-open it line buffered
        if isapipe(sys.stdout):
            # Hold a reference to the previous file object so it doesn't
            # get garbage collected and close the underlying descriptor.
            stdout = sys.stdout
            sys.stdout = os.fdopen(stdout.fileno(), 'w', 1)

        # Quiet printing of KeyboardInterrupt by greenlets
        Hub = gevent.hub.Hub
        Hub.NOT_ERROR = Hub.NOT_ERROR + (KeyboardInterrupt,)

        config = os.environ.get('AGENT_CONFIG')
        identity = os.environ.get('AGENT_VIP_IDENTITY', identity)
        if identity is not None:
            if not is_valid_identity(identity):
                _log.warn('Deprecation warining')
                _log.warn(
                    'All characters in {identity} are not in the valid set.'
                    .format(idenity=identity))

        address = get_address()
        agent_uuid = os.environ.get('AGENT_UUID')
        volttron_home = get_home()

        agent = agent_class(config_path=config, identity=identity,
                            address=address, agent_uuid=agent_uuid,
                            volttron_home=volttron_home,
                            version=version, **kwargs)
        
        try:
            run = agent.run
        except AttributeError:
            run = agent.core.run
        task = gevent.spawn(run)
        try:
            task.join()
        finally:
            task.kill()
    except KeyboardInterrupt:
        pass
예제 #24
0
def vip_main(agent_class, identity=None, **kwargs):
    """Default main entry point implementation for VIP agents."""
    try:
        # If stdout is a pipe, re-open it line buffered
        if isapipe(sys.stdout):
            # Hold a reference to the previous file object so it doesn't
            # get garbage collected and close the underlying descriptor.
            stdout = sys.stdout
            sys.stdout = os.fdopen(stdout.fileno(), 'w', 1)

        # Quiet printing of KeyboardInterrupt by greenlets
        Hub = gevent.hub.Hub
        Hub.NOT_ERROR = Hub.NOT_ERROR + (KeyboardInterrupt, )

        config = os.environ.get('AGENT_CONFIG')
        identity = os.environ.get('AGENT_VIP_IDENTITY', identity)
        address = get_address()
        agent_uuid = os.environ.get('AGENT_UUID')
        volttron_home = get_home()

        agent = agent_class(config_path=config,
                            identity=identity,
                            address=address,
                            agent_uuid=agent_uuid,
                            volttron_home=volttron_home,
                            **kwargs)
        try:
            run = agent.run
        except AttributeError:
            run = agent.core.run
        task = gevent.spawn(run)
        try:
            task.join()
        finally:
            task.kill()
    except KeyboardInterrupt:
        pass
예제 #25
0
    def __init__(self,
                 tls_private_key=None,
                 tls_public_key=None,
                 web_secret_key=None):

        self.refresh_token_timeout = 240  # minutes before token expires. TODO: Should this be a setting somewhere?
        self.access_token_timeout = 15  # minutes before token expires. TODO: Should this be a setting somewhere?
        self._tls_private_key = tls_private_key
        self._tls_public_key = tls_public_key
        self._web_secret_key = web_secret_key
        if self._tls_private_key is None and self._web_secret_key is None:
            raise ValueError(
                "Must have either ssl_private_key or web_secret_key specified!"
            )
        if self._tls_private_key is not None and self._web_secret_key is not None:
            raise ValueError(
                "Must use either ssl_private_key or web_secret_key not both!")
        self._userdict = None
        self.reload_userdict()
        self._observer = Observer()
        self._observer.schedule(
            VolttronHomeFileReloader("web-users.json", self.reload_userdict),
            get_home())
        self._observer.start()
예제 #26
0
    def __init__(self, certificate_dir=None):
        """Creates a Certs instance"""

        self.default_certs_dir = os.path.join(get_home(), 'certificates')
        self.root_ca_name = get_platform_instance_name() + '-root-ca'
        self.trusted_ca_name = get_platform_instance_name() + '-trusted-cas'
        self.default_root_ca_cn = '{} {}'.format(gethostname(),
                                                 self.root_ca_name)

        if not certificate_dir:
            certificate_dir = self.default_certs_dir
            # If user provided explicit directory then it should exist
            if not os.path.exists(certificate_dir):
                if certificate_dir != self.default_certs_dir:
                    raise ValueError('Invalid cert_dir {}'.format(self.cert_dir))

        self.cert_dir = os.path.join(os.path.expanduser(certificate_dir),
                                     'certs')
        self.private_dir = os.path.join(os.path.expanduser(certificate_dir),
                                        'private')
        self.ca_db_dir = os.path.join(os.path.expanduser(certificate_dir),
                                      'ca_db')
        self.csr_pending_dir = os.path.join(os.path.expanduser(certificate_dir),
                                            'pending_csr')
        self.remote_cert_dir = os.path.join(os.path.expanduser(certificate_dir),
                                            'remote_certs')
        self.certs_pending_dir = os.path.join(os.path.expanduser(certificate_dir),
                                              'pending_certs')
        self.rejected_dir = os.path.join(os.path.expanduser(certificate_dir),
                                         'rejected')

        required_paths = (self.cert_dir, self.private_dir, self.ca_db_dir,
                          self.csr_pending_dir, self.remote_cert_dir, self.certs_pending_dir)
        for p in required_paths:
            if not os.path.exists(p):
                os.makedirs(p, 0o755)
예제 #27
0
def main():
    # parse the command line arguments
    arg_parser = argparse.ArgumentParser(description=__doc__)

    arg_parser.add_argument(
        "--address", help="Target only device(s) at <address> for request")

    arg_parser.add_argument(
        "--range",
        type=int,
        nargs=2,
        metavar=('LOW', 'HIGH'),
        help="Lower and upper limit on device ID in results")

    arg_parser.add_argument(
        "--timeout",
        type=int,
        metavar=('SECONDS'),
        help="Time, in seconds, to wait for responses. Default: %(default)s",
        default=5)

    arg_parser.add_argument("--proxy-id",
                            help="VIP IDENTITY of the BACnet proxy agent.",
                            default="platform.bacnet_proxy")

    arg_parser.add_argument("--csv-out",
                            dest="csv_out",
                            help="Write results to the CSV file specified.")

    arg_parser.add_argument("--debug",
                            action="store_true",
                            help="Set the logger in debug mode")

    args = arg_parser.parse_args()

    core_logger = logging.getLogger("volttron.platform.vip.agent.core")
    core_logger.setLevel(logging.WARN)
    _log.setLevel(logging.WARN)

    if args.debug:
        _log.setLevel(logging.DEBUG)
        core_logger.setLevel(logging.DEBUG)

    _log.debug("initialization")
    _log.debug("    - args: %r", args)

    csv_writer = None

    if args.csv_out is not None:
        f = open(args.csv_out, "wb")
        field_names = [
            "address", "device_id", "max_apdu_length",
            "segmentation_supported", "vendor_id"
        ]
        csv_writer = csv.DictWriter(f, field_names)
        csv_writer.writeheader()

    keystore = KeyStore()
    agent = BACnetInteraction(args.proxy_id,
                              csv_writer=csv_writer,
                              address=get_address(),
                              volttron_home=get_home(),
                              publickey=keystore.public,
                              secretkey=keystore.secret,
                              enable_store=False)

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

    kwargs = {'address': args.address}

    if args.range is not None:
        kwargs['low_device_id'] = int(args.range[0])
        kwargs['high_device_id'] = int(args.range[1])

    try:
        agent.send_iam(**kwargs)
    except errors.Unreachable:
        _log.error(
            "There is no BACnet proxy Agent running on the platform with the VIP IDENTITY {}"
            .format(args.proxy_id))
    else:
        gevent.sleep(args.timeout)
예제 #28
0
파일: agent.py 프로젝트: miraabid/bemoss
    def launch_new_app(self, ui_app_name, ui_agent_id):
        self.curcon.execute(
            "SELECT app_name, executable FROM " +
            db_table_application_registered + " WHERE app_name=%s",
            (ui_app_name, ))
        # 1. launch app for an agent based on the exec file and agent_id
        if self.curcon.rowcount != 0:
            app_info = self.curcon.fetchone()
            _exec_name = str(app_info[1])
            _exec = _exec_name + "-0.1-py2.7.egg --config \"%c\" --sub \"%s\" --pub \"%p\""
            data = {"agent": {"exec": _exec}, "agent_id": ui_agent_id}
            PROJECT_DIR = settings.PROJECT_DIR
            env_path = settings.PROJECT_DIR + '/env/bin/'
            _launch_file = os.path.join(
                PROJECT_DIR, "Applications/launch/" + str(ui_app_name) + "_" +
                str(ui_agent_id))
            if debug_agent: print(_launch_file)
            with open(_launch_file, 'w') as outfile:
                json.dump(data, outfile, indent=4, sort_keys=True)
            if debug_agent: print(os.path.basename(_launch_file))

            os.system("volttron-ctl status > app_running_agent.txt")
            infile = open('app_running_agent.txt', 'r')
            installed = False
            for line in infile:
                # print(line, end='') #write to a next file name outfile
                match = re.search(ui_app_name + '_' + ui_agent_id, line)
                if match:  # The app that ui requested has not been installed.
                    print "APP: {}, APP has actually been installed. Just starting"\
                        .format(ui_app_name)
                    installed = True

            if not installed:
                os.system(  # ". env/bin/activate"
                    env_path + "volttron-pkg configure " + platform.get_home() + "/packaged/" + ui_app_name + "-3.0-py2-none-any.whl " + _launch_file + ";" + \
                    env_path + "volttron-ctl install " + ui_app_name+"_"+ui_agent_id + "=" + platform.get_home() + "/packaged/" + ui_app_name + "-3.0-py2-none-any.whl;")

            os.system("volttron-ctl start --tag " +
                      os.path.basename(_launch_file))
            os.system("volttron-ctl status")

            print "AppLauncher has successfully launched APP: {} for Agent: {}"\
                .format(ui_app_name, ui_agent_id)
            # send reply back to UI
            _topic_appLauncher_ui = '/appLauncher/ui/' + ui_app_name + '/' + ui_agent_id + '/' + 'launch/response'
            _headers = {
                headers_mod.FROM: app_name,
                headers_mod.CONTENT_TYPE: headers_mod.CONTENT_TYPE.JSON,
            }
            _message = "success"
            self.vip.pubsub.publish('pubsub', _topic_appLauncher_ui, _headers,
                                    _message)
            # self.app_number += 1
            self.curcon.execute(
                "SELECT description FROM " + db_table_application_registered +
                " WHERE app_name=%s", (ui_app_name, ))
            if self.curcon.rowcount != 0:
                _app_description = str(self.curcon.fetchone()[0])
                print "The description of APP: {} is {}".format(
                    ui_app_name, _app_description)
            else:
                print "AppLauncher failed to get APP: {} description".format(
                    ui_app_name)

            # 2. log app that has been launched to the database
            _launch_file_name = str(ui_app_name) + "_" + str(ui_agent_id)
            _start_time = str(datetime.datetime.now())
            _app_status = "running"
            self.curcon.execute("SELECT id FROM " +
                                db_table_application_running)
            if self.curcon.rowcount != 0:
                # print 'cur.fetchall()' + str(max(cur.fetchall())[0])
                app_no = max(self.curcon.fetchall())[0] + 1
            else:  #default no_app
                app_no = 1
            self.curcon.execute(
                "INSERT INTO application_running(id, app_agent_id, start_time, status, app_type, app_data) "
                "VALUES(%s,%s,%s,%s,%s,%s)",
                (app_no, _launch_file_name, _start_time, _app_status,
                 app_info[0], '{}'))
            self.curcon.commit()
            print "AppLauncher finished update table applications_running of APP: {}".format(
                ui_app_name)
            print "with launch_file: {}, at timestamp {}".format(
                _launch_file, _start_time)
        else:
            print "AppLauncher failed to launch APP: {} for Agent: {}".format(
                ui_app_name, ui_agent_id)
예제 #29
0
            if k < keylen - 1:
                keyline += "%s," % keys[k]
                valueline += "%s," % output_dict[keys[k]]
            else:
                keyline += "%s" % keys[k]
                valueline += "%s" % output_dict[keys[k]]
        sys.stdout.write("%s\n%s\n" % (keyline, valueline))


if __name__ == '__main__':

    parser = argparse.ArgumentParser(version=__version__)

    parser.add_argument("-a", "--vip-address", default=get_address(),
                        help="vip-address to connect to.")
    parser.add_argument("-vh", "--volttron-home", default=get_home(),
                        help="local volttron-home for the instance.")
    parser.add_argument("-vr", "--volttron-root", default=get_volttron_root(),
                        help="location of the volttron root on the filesystem.")
    parser.add_argument("-s", "--agent-source", required=True,
                        help="source directory of the agent which is to be installed.")
    parser.add_argument("-i", "--vip-identity", default=None,
                        help="identity of the agent to be installed (unique per instance)")
    parser.add_argument("-c", "--config", default=None, type=file,
                        help="agent configuration file that will be packaged with the agent.")
    parser.add_argument("-wh", "--wheelhouse", default=None,
                        help="location of agents after they have been built")
    parser.add_argument("-t", "--tag", default=None,
                        help="a tag is a means of identifying an agent.")
    parser.add_argument("-f", "--force", action='store_true',
                        help="agents are uninstalled by tag so force allows multiple agents to be removed at one go.")
예제 #30
0
if not inenv:
    mypath = os.path.dirname(__file__)
    correct_python = sys.executable
    if not os.path.exists(correct_python):
        log.error("Invalid location for the script {}".format(correct_python))
        sys.exit(-10)

    # Call this script in a subprocess with the correct python interpreter.
    cmds = [correct_python, __file__]
    cmds.extend(sys.argv[1:])
    process = subprocess.Popen(cmds, env=os.environ)
    process.wait()
    sys.exit(process.returncode)

from volttron.platform import get_home, is_instance_running

__version__ = '0.2'

if __name__ == '__main__':

    parser = argparse.ArgumentParser(version=__version__)
    parser.add_argument("-vh", "--volttron-home", default=get_home())

    args = parser.parse_args()
    result = is_instance_running(args.volttron_home)
    if result:
        result = 1
    else:
        result = 0
    sys.stdout.write("{}\n".format(int(result)))
예제 #31
0
파일: agent.py 프로젝트: miraabid/bemoss
    def launch_existing_app(self, ui_app_name, ui_agent_id):
        self.curcon.execute(
            "SELECT executable FROM " + db_table_application_registered +
            " WHERE app_name=%s", (ui_app_name, ))
        # 1. launch app for an agent based on the exec file and agent_id
        if self.curcon.rowcount != 0:
            _exec_name = str(self.curcon.fetchone()[0])
            _exec = _exec_name + "-3.0-py2.7.egg --config \"%c\" --sub \"%s\" --pub \"%p\""
            data = {
                "agent": {
                    "exec": _exec
                },
                "agent_id": ui_app_name + '_' + ui_agent_id
            }
            PROJECT_DIR = settings.PROJECT_DIR
            _launch_file = os.path.join(
                PROJECT_DIR, "Applications/launch/" + str(ui_app_name) + "_" +
                str(ui_agent_id))
            if debug_agent: print(_launch_file)
            with open(_launch_file, 'w') as outfile:
                json.dump(data, outfile, indent=4, sort_keys=True)
            if debug_agent: print(os.path.basename(_launch_file))
            os.system("volttron-ctl status > app_running_agent.txt")
            infile = open('app_running_agent.txt', 'r')
            installed = False
            for line in infile:
                # print(line, end='') #write to a next file name outfile
                match = re.search(ui_app_name + '_' + ui_agent_id, line)
                if match:  # The app that ui requested has not been installed.
                    print "APP: {}, APP has actually been installed. Just starting".format(
                        ui_app_name)
                    installed = True
                    break

            if not installed:
                env_path = settings.PROJECT_DIR + '/env/bin/'
                os.system(  # ". env/bin/activate"
                    env_path + "volttron-pkg configure " + platform.get_home() + "/packaged/" + ui_app_name + "-3.0-py2-none-any.whl " + _launch_file + ";" + \
                    env_path + "volttron-ctl install " + ui_app_name+"_"+ui_agent_id + "=" + platform.get_home() + "/packaged/" + ui_app_name + "-3.0-py2-none-any.whl;")

            os.system("volttron-ctl start --tag " +
                      os.path.basename(_launch_file))
            os.system("volttron-ctl status")
            print "AppLauncher has successfully launched APP: {} for Agent: {}"\
                .format(ui_app_name, ui_agent_id)
            self.curcon.execute(
                "UPDATE application_running SET status=%s WHERE app_agent_id=%s",
                (
                    "running",
                    ui_app_name + "_" + ui_agent_id,
                ))
            self.curcon.commit()
            # send reply back to UI
            _topic_appLauncher_ui = '/appLauncher/ui/' + ui_app_name + '/' + ui_agent_id + '/' + 'launch/response'
            _headers = {
                headers_mod.FROM: app_name,
                headers_mod.CONTENT_TYPE: headers_mod.CONTENT_TYPE.JSON,
            }
            _message = "success"
            self.vip.pubsub.publish('pubsub', _topic_appLauncher_ui, _headers,
                                    _message)
예제 #32
0
 def get_default_path():
     return os.path.join(get_home(), 'keystore')
예제 #33
0
def main():
    global agent
    global config_writer
    # parse the command line arguments
    arg_parser = argparse.ArgumentParser(description=__doc__)

    arg_parser.add_argument("device_id",
                            type=int,
                            help="Device ID of the target device")

    arg_parser.add_argument(
        "--address",
        help=
        "Address of target device, may be needed to help route initial request to device."
    )

    arg_parser.add_argument("--registry-out-file",
                            type=argparse.FileType('w'),
                            help="Output registry to CSV file",
                            default=sys.stdout)

    arg_parser.add_argument("--driver-out-file",
                            type=argparse.FileType('w'),
                            help="Output driver configuration to JSON file.",
                            default=sys.stdout)

    arg_parser.add_argument(
        "--max-range-report",
        nargs='?',
        type=float,
        help=
        'Affects how very large numbers are reported in the "Unit Details" column of the '
        'output. Does not affect driver behavior.',
        default=1.0e+20)

    arg_parser.add_argument("--proxy-id",
                            help="VIP IDENTITY of the BACnet proxy agent.",
                            default="platform.bacnet_proxy")

    args = arg_parser.parse_args()

    _log.debug("initialization")
    _log.debug("    - args: %r", args)

    key_store = KeyStore()
    config_writer = DictWriter(
        args.registry_out_file,
        ('Reference Point Name', 'Volttron Point Name', 'Units',
         'Unit Details', 'BACnet Object Type', 'Property', 'Writable', 'Index',
         'Write Priority', 'Notes'))

    config_writer.writeheader()

    agent = build_agent(address=get_address(),
                        volttron_home=get_home(),
                        publickey=key_store.public,
                        secretkey=key_store.secret,
                        enable_store=False)

    bn = BACnetReader(agent.vip, args.proxy_id, bacnet_response)

    async_result = AsyncResult()

    try:
        bn.get_iam(args.device_id, async_result.set, args.address)
    except errors.Unreachable as ure:
        _log.error(ure)
        _log.error(
            "No BACnet proxy Agent running on the platform with the VIP IDENTITY {}"
            .format(args.proxy_id))
        sys.exit(1)

    try:
        results = async_result.get(timeout=5.0)
    except gevent.Timeout:
        _log.error("No response from device id {}".format(args.device_id))
        sys.exit(1)

    if args.address and args.address != results["address"]:
        msg = "Inconsistent results from passed address ({}) and device address ({}) using results.".format(
            args.address, results["address"])
        _log.warning(msg)
        args.address = results["address"]
    elif results["address"]:
        args.address = results["address"]

    bn.read_device_properties(target_address=args.address,
                              device_id=args.device_id)

    agent.core.stop()
예제 #34
0
def setup_rabbitmq_volttron(setup_type, verbose=False, prompt=False, instance_name=None,
                            rmq_conf_file=None, env=None):
    """
    Setup VOLTTRON instance to run with RabbitMQ message bus.
    :param setup_type:
            single - Setup to run as single instance
            federation - Setup to connect multiple VOLTTRON instances as
                         a federation
            shovel - Setup shovels to forward local messages to remote instances
    :param verbose
    :param prompt
    :raises RabbitMQSetupAlreadyError
    """
    if not instance_name:
        instance_name = get_platform_instance_name(prompt=True)
    # Store config this is checked at startup
    store_message_bus_config(message_bus='rmq', instance_name=instance_name)

    rmq_config = RMQConfig()
    if verbose:
        _log.setLevel(logging.DEBUG)
        _log.debug("verbose set to True")
        _log.debug(get_home())
        logging.getLogger("requests.packages.urllib3.connectionpool"
                          "").setLevel(logging.DEBUG)
    else:
        _log.setLevel(logging.INFO)
        logging.getLogger("requests.packages.urllib3.connectionpool"
                          "").setLevel(logging.WARN)

    if prompt:
        # ignore any existing rabbitmq_config.yml in vhome. Prompt user and
        # generate a new rabbitmq_config.yml
        _create_rabbitmq_config(rmq_config, setup_type)

    # Load either the newly created config or config passed
    try:
        rmq_config.load_rmq_config()

    except (yaml.parser.ParserError, yaml.scanner.ScannerError, yaml.YAMLError) as exc:
        _log.error("Error: YAML file cannot parsed properly. Check the contents of the file")
        return exc

    except IOError as exc:
        _log.error("Error opening {}. Please create a rabbitmq_config.yml "
                   "file in your volttron home. If you want to point to a "
                   "volttron home other than {} please set it as the "
                   "environment variable VOLTTRON_HOME".format(
            rmq_config.volttron_rmq_config, rmq_config.volttron_home))
        _log.error("\nFor single setup, configuration file must at least "
                   "contain host and ssl certificate details. For federation "
                   "and shovel setup, config should contain details about the "
                   "volttron instance with which communication needs "
                   "to be established. Please refer to example config file "
                   "at examples/configurations/rabbitmq/rabbitmq_config.yml")
        raise

    if not rmq_conf_file:
        rmq_conf_file = os.path.join(rmq_config.rmq_home, "etc/rabbitmq/rabbitmq.conf")

    invalid = True
    if setup_type in ["all", "single"]:
        invalid = False
        # Verify that the rmq_conf_file if exists is removed before continuing.
        message = f"A rabbitmq conf file {rmq_conf_file} already exists.\n" \
                  "In order for setup to proceed it must be removed.\n"
        if os.path.exists(rmq_conf_file):
            print(message)
            while os.path.exists(rmq_conf_file):
                value = prompt_response(f"Remove {rmq_conf_file}? ", y_or_n)
                if value in y:
                    os.remove(rmq_conf_file)

        _start_rabbitmq_without_ssl(rmq_config, rmq_conf_file, env=env)
        _log.debug("Creating rabbitmq virtual hosts and required users for "
                   "volttron")
        # Create local RabbitMQ setup - vhost, exchange etc.
        # should be called after _start_rabbitmq_without_ssl
        rmq_mgmt = RabbitMQMgmt()
        success = rmq_mgmt.init_rabbitmq_setup()
        if success and rmq_config.is_ssl:
            _setup_for_ssl_auth(rmq_config, rmq_conf_file, env=env)

        # Create utility scripts
        script_path = os.path.dirname(os.path.realpath(__file__))
        src_home = os.path.dirname(os.path.dirname(script_path))
        start_script = os.path.join(src_home, 'start-rabbitmq')
        with open(start_script, 'w+') as f:
            f.write(os.path.join(rmq_config.rmq_home, 'sbin',
                                 'rabbitmq-server') + ' -detached')
            f.write(os.linesep)
            f.write("sleep 5")  # give a few seconds for all plugins to be ready
        os.chmod(start_script, 0o755)

        stop_script = os.path.join(src_home, 'stop-rabbitmq')
        with open(stop_script, 'w+') as f:
            f.write(os.path.join(rmq_config.rmq_home, 'sbin',
                                 'rabbitmqctl') + ' stop')
        os.chmod(stop_script, 0o755)

        # symlink to rmq log
        log_name = os.path.join(src_home, 'rabbitmq.log')
        if os.path.lexists(log_name):
            os.unlink(log_name)

        os.symlink(os.path.join(rmq_config.rmq_home,
                                'var/log/rabbitmq',
                                rmq_config.node_name + "@" +
                                rmq_config.hostname.split('.')[0] + ".log"),
                   log_name)

    if setup_type in ["all", "federation"]:
        # Create a multi-platform federation setup
        invalid = False
        _create_federation_setup(rmq_config.admin_user,
                                 rmq_config.admin_pwd,
                                 rmq_config.is_ssl,
                                 rmq_config.virtual_host,
                                 rmq_config.volttron_home)
    if setup_type in ["all", "shovel"]:
        # Create shovel setup
        invalid = False
        if rmq_config.is_ssl:
            port = rmq_config.amqp_port_ssl
        else:
            port = rmq_config.amqp_port
        _create_shovel_setup(rmq_config.instance_name,
                             rmq_config.hostname,
                             port,
                             rmq_config.virtual_host,
                             rmq_config.volttron_home,
                             rmq_config.is_ssl)
    if invalid:
        _log.error("Unknown option. Exiting....")
예제 #35
0
def _create_rabbitmq_config(rmq_config, setup_type):
    """
    Prompt user for required details and create a rabbitmq_config.yml file in
    volttron home
    :param setup_type: type of rmq setup - single, federation, shovel or all
    """

    if setup_type == 'single' or setup_type == 'all':
        if os.path.exists(rmq_config.volttron_rmq_config):
            prompt = "rabbitmq_config.yml exists in {} Do you wish to " \
                     "use this file to configure the instance".format(
                get_home())
            prompt = prompt_response(prompt,
                                     valid_answers=y_or_n,
                                     default='Y')
            if prompt in y:
                return
            else:
                _log.info("New input data will be used to overwrite existing "
                          "{}".format(rmq_config.volttron_rmq_config))
                # TODO: ideally we can load existing file and set values in it
                # default and the compare what changed. If rmq-home changed
                # and existing config those should get cleared. If cert details
                # get changed - overwrite ca, server, admin cert and delete all
                # other certs.

        rmq_config.rmq_home = _prompt_rmq_home(rmq_config.rabbitmq_server)

        prompt = 'Fully qualified domain name of the system:'
        new_host = prompt_response(prompt, default=getfqdn())
        rmq_config.hostname = new_host

        rmq_config.is_ssl = True

        if rmq_config.is_ssl:
            prompt = "Would you like to create a new self signed root CA" \
                     "certificate for this instance:"
            prompt = prompt_response(prompt,
                                     valid_answers=y_or_n,
                                     default='Y')
            if prompt in y:
                cert_data = {}
                print(
                    "\nPlease enter the following details for root CA certificate")
                prompt = '\tCountry:'
                cert_data['country'] = prompt_response(prompt, default='US')
                prompt = '\tState:'
                cert_data['state'] = prompt_response(prompt, mandatory=True)
                prompt = '\tLocation:'
                cert_data['location'] = prompt_response(prompt, mandatory=True)
                prompt = '\tOrganization:'
                cert_data['organization'] = prompt_response(prompt, mandatory=True)
                prompt = '\tOrganization Unit:'
                cert_data['organization-unit'] = prompt_response(prompt,
                                                                 mandatory=True)
                cert_data['common-name'] = rmq_config.instance_name + '-root-ca'
                rmq_config.certificate_data = cert_data
            else:
                error = True
                while error:
                    while True:
                        prompt = 'Enter the root CA certificate public key file:'
                        root_public = prompt_response(prompt, mandatory=True)
                        if is_file_readable(root_public):
                            break
                    while True:
                        prompt =\
                            'Enter the root CA certificate private key file:'
                        root_key = prompt_response(prompt, mandatory=True)
                        if is_file_readable(root_key):
                            break
                    if certs.Certs.validate_key_pair(root_public, root_key):
                        error = False
                        cert_data = {
                            'ca-public-key': root_public,
                            'ca-private-key': root_key
                        }
                        rmq_config.certificate_data = cert_data
                    else:
                        print("Error: Given public key and private key do not "
                              "match or is invalid. public and private key "
                              "files should be PEM encoded and private key "
                              "should use RSA encryption")

        prompt = "Do you want to use default values for RabbitMQ home, " \
                 "ports, and virtual host:"
        prompt = prompt_response(prompt,
                                 valid_answers=y_or_n,
                                 default='Y')
        if prompt in y:
            rmq_config.amqp_port = '5672'
            rmq_config.mgmt_port = '15672'
            rmq_config.amqp_port_ssl = '5671'
            rmq_config.mgmt_port_ssl = '15671'
            rmq_config.virtual_host = 'volttron'
        else:
            rmq_config.virtual_host = _prompt_vhost(rmq_config.config_opts)

            prompt = 'AMQP port for RabbitMQ:'
            rmq_config.amqp_port = prompt_port(5672, prompt)

            prompt = 'http port for the RabbitMQ management plugin:'
            rmq_config.mgmt_port = prompt_port(15672, prompt)

            if rmq_config.is_ssl:
                prompt = 'AMQPS (SSL) port RabbitMQ address:'
                rmq_config.amqp_port_ssl = prompt_port(5671, prompt)

                prompt = 'https port for the RabbitMQ management plugin:'
                rmq_config.mgmt_port_ssl = prompt_port(15671, prompt)

        # Write the new config options back to config file
        rmq_config.write_rmq_config()
    if setup_type in ['federation', 'all']:
        # if option was all then config_opts would be not null
        # if this was called with just setup_type = federation, load existing
        # config so that we don't overwrite existing federation configs
        prompt_upstream_servers(rmq_config.volttron_home)
    if setup_type in ['shovel', 'all']:
        # if option was all then config_opts would be not null
        # if this was called with just setup_type = shovel, load existing
        # config so that we don't overwrite existing list
        prompt_shovels(rmq_config.volttron_home)
예제 #36
0
def main():
    # parse the command line arguments
    arg_parser = argparse.ArgumentParser(description=__doc__)

    arg_parser.add_argument("--address",
                            help="Target only device(s) at <address> for request")

    arg_parser.add_argument("--range", type=int, nargs=2, metavar=('LOW', 'HIGH'),
                            help="Lower and upper limit on device ID in results")

    arg_parser.add_argument("--timeout", type=int, metavar=('SECONDS'),
                            help="Time, in seconds, to wait for responses. Default: %(default)s",
                            default=5)

    arg_parser.add_argument("--proxy-id",
                            help="VIP IDENTITY of the BACnet proxy agent.",
                            default="platform.bacnet_proxy")

    arg_parser.add_argument("--csv-out", dest="csv_out",
                            help="Write results to the CSV file specified.")

    arg_parser.add_argument("--debug", action="store_true",
                            help="Set the logger in debug mode")
    
    args = arg_parser.parse_args()

    core_logger = logging.getLogger("volttron.platform.vip.agent.core")
    core_logger.setLevel(logging.WARN)
    _log.setLevel(logging.WARN)

    if args.debug:
        _log.setLevel(logging.DEBUG)
        core_logger.setLevel(logging.DEBUG)

    _log.debug("initialization")
    _log.debug("    - args: %r", args)

    csv_writer = None

    if args.csv_out is not None:
        f = open(args.csv_out, "wb")
        field_names = ["address",
                       "device_id",
                       "max_apdu_length",
                       "segmentation_supported",
                       "vendor_id"]
        csv_writer = csv.DictWriter(f, field_names)
        csv_writer.writeheader()

    keystore = KeyStore()
    agent = BACnetInteraction(args.proxy_id,
                              csv_writer=csv_writer,
                              address=get_address(),
                              volttron_home=get_home(),
                              publickey=keystore.public,
                              secretkey=keystore.secret,
                              enable_store=False)

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

    kwargs = {'address': args.address}

    if args.range is not None:
        kwargs['low_device_id'] = int(args.range[0])
        kwargs['high_device_id'] = int(args.range[1])

    try:
        agent.send_iam(**kwargs)
    except errors.Unreachable:
        _log.error("There is no BACnet proxy Agent running on the platform with the VIP IDENTITY {}".format(args.proxy_id))
    else:
        gevent.sleep(args.timeout)
예제 #37
0
 def __init__(self, filename=None):
     if filename is None:
         filename = os.path.join(get_home(), 'known_hosts')
     super(KnownHostsStore, self).__init__(filename)
예제 #38
0
def main():
    global agent
    global config_writer
    # parse the command line arguments
    arg_parser = argparse.ArgumentParser(description=__doc__)

    arg_parser.add_argument("device_id", type=int,
                            help="Device ID of the target device" )

    arg_parser.add_argument("--address",
                            help="Address of target device, may be needed to help route initial request to device." )

    arg_parser.add_argument("--registry-out-file", type=argparse.FileType('wb'),
                            help="Output registry to CSV file",
                            default=sys.stdout )

    arg_parser.add_argument("--driver-out-file", type=argparse.FileType('wb'),
                            help="Output driver configuration to JSON file.",
                            default=sys.stdout)

    arg_parser.add_argument("--max-range-report", nargs='?', type=float,
                            help='Affects how very large numbers are reported in the "Unit Details" column of the output. '
                            'Does not affect driver behavior.',
                            default=1.0e+20 )

    arg_parser.add_argument("--proxy-id",
                            help="VIP IDENTITY of the BACnet proxy agent.",
                            default="platform.bacnet_proxy")

    args = arg_parser.parse_args()

    _log.debug("initialization")
    _log.debug("    - args: %r", args)

    key_store = KeyStore()
    config_writer = DictWriter(args.registry_out_file,
                              ('Reference Point Name',
                               'Volttron Point Name',
                               'Units',
                               'Unit Details',
                               'BACnet Object Type',
                               'Property',
                               'Writable',
                               'Index',
                               'Write Priority',
                               'Notes'))

    config_writer.writeheader()

    agent = build_agent(address=get_address(),
                        volttron_home=get_home(),
                        publickey=key_store.public,
                        secretkey=key_store.secret,
                        enable_store=False)

    bn = BACnetReader(agent.vip, args.proxy_id, bacnet_response)

    async_result = AsyncResult()

    try:
        bn.get_iam(args.device_id, async_result.set, args.address)
    except errors.Unreachable:
        msg = "No BACnet proxy Agent running on the platform with the " \
              "VIP IDENTITY {}".format(args.proxy_id)
        sys.exit(1)

    try:
        results = async_result.get(timeout=5.0)
    except gevent.Timeout:
        _log.error("No response from device id {}".format(args.device_id))
        sys.exit(1)

    if args.address and args.address != results["address"]:
        msg = "Inconsistent results from passed address " \
              "({}) and device address ({}) using results.".format(
            args.address, results["address"])
        _log.warning(msg)
        args.address = results["address"]
    elif results["address"]:
        args.address = results["address"]

    bn.read_device_properties(target_address=args.address,
                              device_id=args.device_id)

    agent.core.stop()
def main():
    global agent
    # parse the command line arguments
    arg_parser = argparse.ArgumentParser(description=__doc__)
        
    arg_parser.add_argument("device_id", type=int,
                            help="Device ID of the target device" )
    
    arg_parser.add_argument("--address",
                            help="Address of target device, may be needed to help route initial request to device." )
    
    arg_parser.add_argument("--registry-out-file", type=argparse.FileType('wb'),
                            help="Output registry to CSV file",
                            default=sys.stdout )

    arg_parser.add_argument("--driver-out-file", type=argparse.FileType('wb'),
                            help="Output driver configuration to JSON file.",
                            default=sys.stdout)
    
    arg_parser.add_argument("--max-range-report", nargs='?', type=float,
                            help='Affects how very large numbers are reported in the "Unit Details" column of the output. ' 
                            'Does not affect driver behavior.',
                            default=1.0e+20 )

    arg_parser.add_argument("--proxy-id",
                            help="VIP IDENTITY of the BACnet proxy agent.",
                            default="platform.bacnet_proxy")
    
    args = arg_parser.parse_args()

    _log.debug("initialization")
    _log.debug("    - args: %r", args)

    key_store = KeyStore()
    agent = BACnetInteraction(args.proxy_id,
                              address=get_address(),
                              volttron_home=get_home(),
                              publickey=key_store.public,
                              secretkey=key_store.secret,
                              enable_store=False)

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

    async_result = AsyncResult()

    try:
        agent.get_iam(args.device_id, async_result.set, args.address)
    except errors.Unreachable:
        _log.error("There is no BACnet proxy Agent running on the platform with the VIP IDENTITY {}".format(args.proxy_id))
        sys.exit(1)

    try:
        results = async_result.get(timeout=5.0)
    except gevent.Timeout:
        _log.error("No response from device id {}".format(args.device_id))
        sys.exit(1)

    target_address = results["address"]
    device_id = results["device_id"]

    config_file_name = basename(args.registry_out_file.name)

    config = {
        "driver_config": {"device_address": str(target_address),
                          "device_id": device_id},
        "driver_type": "bacnet",
        "registry_config": "config://registry_configs/{}".format(config_file_name)
    }

    json.dump(config, args.driver_out_file, indent=4)
    
    _log.debug('pduSource = ' + target_address)
    _log.debug('iAmDeviceIdentifier = ' + str(device_id))
    _log.debug('maxAPDULengthAccepted = ' + str(results["max_apdu_length"]))
    _log.debug('segmentationSupported = ' + results["segmentation_supported"])
    _log.debug('vendorID = ' + str(results["vendor_id"]))
    
    try:
        device_name = read_prop(target_address, "device", device_id, "objectName")
        _log.debug('device_name = ' + str(device_name))
    except TypeError:
        _log.debug('device missing objectName')
    
    try:
        device_description = read_prop(target_address, "device", device_id, "description")
        _log.debug('description = ' + str(device_description))
    except TypeError:
        _log.debug('device missing description')
    
    
    
    config_writer = DictWriter(args.registry_out_file,
                               ('Reference Point Name',
                                'Volttron Point Name',
                                'Units',
                                'Unit Details',
                                'BACnet Object Type',
                                'Property',
                                'Writable',
                                'Index',
                                'Write Priority',
                                'Notes'))
    
    config_writer.writeheader()
    
    
    try:
        object_count = read_prop(target_address, "device", device_id, "objectList", index=0)
        list_property = "objectList"
    except TypeError:
        object_count = read_prop(target_address, "device", device_id, "structuredObjectList", index=0)
        list_property = "structuredObjectList"
    
    _log.debug('object_count = ' + str(object_count))
    
    for object_index in xrange(1,object_count+1):
        _log.debug('object_device_index = ' + repr(object_index))
        
        bac_object = read_prop(target_address,
                                "device", 
                                device_id, 
                                list_property,
                                index=object_index)
        
        obj_type, index = bac_object
        
        process_object(target_address, obj_type, index, args.max_range_report, config_writer)
예제 #40
0
 def __init__(self, filename=None):
     if filename is None:
         filename = os.path.join(get_home(), 'keystore')
     super(KeyStore, self).__init__(filename)
     if not self.isvalid():
         self.generate()