text: # -*- coding: utf-8 -*-
  # ---------------------------------------------------------------------
  # Initialize inventory hierarchy
  # ---------------------------------------------------------------------
  # Copyright (C) 2007-2019 The NOC Project
  # See LICENSE for details
  # ---------------------------------------------------------------------
  
  # Python modules
  from __future__ import print_function
  
  # NOC modules
  from noc.core.migration.base import BaseMigration
  
  
  class Migration(BaseMigration):
  
      ROOT_UUID = "0f1b7c90-c611-4046-9a83-b120377eb6e0"
      LOST_N_FOUND_UUID = "b0fae773-b214-4edf-be35-3468b53b03f2"
  
      def migrate(self):
          db = self.mongo_db
          # Initialize container models
          om = db.noc.objectmodels
          root = om.find_one({"name": "Root"})
          if not root:
              print("    Create Root model stub")
              root = om.insert_one(
                  {"name": "Root", "uuid": self.ROOT_UUID, "data": {"container": {"container": True}}}
              )
              root = root.inserted_id
          else:
              root = root["_id"]
          lost_and_found = om.find_one({"name": "Lost&Found"})
          if not lost_and_found:
              print("    Create Lost&Found model stub")
              lost_and_found = om.insert_one(
                  {
                      "name": "Lost&Found",
                      "uuid": self.LOST_N_FOUND_UUID,
                      "data": {"container": {"container": True}},
                  }
              )
              lost_and_found = lost_and_found.inserted_id
          else:
              lost_and_found = lost_and_found["_id"]
          # Create root object
          objects = db.noc.objects
          r = objects.insert_one({"name": "Root", "model": root})
          r = r.inserted_id
          lf = objects.insert_one(
              {"name": "Global Lost&Found", "model": lost_and_found, "container": r}
          )
          lf = lf.inserted_id
          # Find all outer connection names
          m_c = {}
          containers = set()
          for m in db.noc.objectmodels.find():
              m_c[m["_id"]] = set(
                  c["name"] for c in m.get("connections", []) if c["direction"] == "o"
              )
              if m.get("data", {}).get("container", {}).get("container", False):
                  containers.add(m["_id"])
          # Assign all unconnected objects to l&f
          for o in db.noc.objects.find():
              if o["model"] in containers:
                  continue
              found = False
              oc = m_c[o["model"]]
              if oc:
                  for c in db.noc.objectconnections.find({"connection.object": o["_id"]}):
                      for cc in c["connection"]:
                          if cc["name"] in oc and cc["object"] == o["_id"]:
                              found = True
                              break
              if not found:
                  # Set container
                  db.noc.objects.update_many({"_id": o["_id"]}, {"$set": {"container": lf}})
  