Feature 10239: Distributed VCA

- Add vca_id in all calls that invoke libjuju. This is for being able to
talk to the default VCA or the VCA associated to the VIM
- Add store.py: Abstraction to talk to the database.
  - DBMongoStore: Use the db from common to talk to the database
  - MotorStore: Use motor, an asynchronous mongodb client to talk to the
database
- Add vca/connection.py: Represents the data needed to connect the VCA
- Add EnvironConfig in config.py: Class to get the environment config,
and avoid LCM from passing that

Change-Id: I28625e0c56ce408114022c83d4b7cacbb649434c
Signed-off-by: David Garcia <david.garcia@canonical.com>
diff --git a/n2vc/n2vc_conn.py b/n2vc/n2vc_conn.py
index 12704a3..bfdf460 100644
--- a/n2vc/n2vc_conn.py
+++ b/n2vc/n2vc_conn.py
@@ -55,9 +55,6 @@
         fs: object,
         log: object,
         loop: object,
-        url: str,
-        username: str,
-        vca_config: dict,
         on_update_db=None,
         **kwargs,
     ):
@@ -68,14 +65,6 @@
             FsBase)
         :param object log: the logging object to log to
         :param object loop: the loop to use for asyncio (default current thread loop)
-        :param str url: a string that how to connect to the VCA (if needed, IP and port
-            can be obtained from there)
-        :param str username: the username to authenticate with VCA
-        :param dict vca_config: Additional parameters for the specific VCA. For example,
-            for juju it will contain:
-            secret: The password to authenticate with
-            public_key: The contents of the juju public SSH key
-            ca_cert str: The CA certificate used to authenticate
         :param on_update_db: callback called when n2vc connector updates database.
             Received arguments:
             table: e.g. "nsrs"
@@ -93,26 +82,10 @@
         if fs is None:
             raise N2VCBadArgumentsException("Argument fs is mandatory", ["fs"])
 
-        self.log.info(
-            "url={}, username={}, vca_config={}".format(
-                url,
-                username,
-                {
-                    k: v
-                    for k, v in vca_config.items()
-                    if k
-                    not in ("host", "port", "user", "secret", "public_key", "ca_cert")
-                },
-            )
-        )
-
         # store arguments into self
         self.db = db
         self.fs = fs
         self.loop = loop or asyncio.get_event_loop()
-        self.url = url
-        self.username = username
-        self.vca_config = vca_config
         self.on_update_db = on_update_db
 
         # generate private/public key-pair
@@ -443,7 +416,18 @@
         detailed_status: str,
         vca_status: str,
         entity_type: str,
+        vca_id: str = None,
     ):
+        """
+        Write application status to database
+
+        :param: db_dict: DB dictionary
+        :param: status: Status of the application
+        :param: detailed_status: Detailed status
+        :param: vca_status: VCA status
+        :param: entity_type: Entity type ("application", "machine, and "action")
+        :param: vca_id: Id of the VCA. If None, the default VCA will be used.
+        """
         if not db_dict:
             self.log.debug("No db_dict => No database write")
             return
@@ -477,10 +461,10 @@
             if self.on_update_db:
                 if asyncio.iscoroutinefunction(self.on_update_db):
                     await self.on_update_db(
-                        the_table, the_filter, the_path, update_dict
+                        the_table, the_filter, the_path, update_dict, vca_id=vca_id
                     )
                 else:
-                    self.on_update_db(the_table, the_filter, the_path, update_dict)
+                    self.on_update_db(the_table, the_filter, the_path, update_dict, vca_id=vca_id)
 
         except DbException as e:
             if e.http_code == HTTPStatus.NOT_FOUND: