Exemple #1
0
def load_builtin_scripts():
    for script in BUILTIN_SCRIPTS:
        if script.inject_file:
            with open(script.inject_path, "r") as f:
                script.substitutes["inject_file"] = f.read()
        script_content = tempita.Template.from_filename(
            script.script_path, encoding="utf-8"
        )
        script_content = script_content.substitute(
            {"name": script.name, **script.substitutes}
        )
        try:
            script_in_db = Script.objects.get(name=script.name)
        except Script.DoesNotExist:
            form = ScriptForm(
                data={
                    "script": script_content,
                    "comment": "Created by maas-%s" % get_maas_version(),
                }
            )
            # Form validation should never fail as these are the scripts which
            # ship with MAAS. If they ever do this will be cause by unit tests.
            if not form.is_valid():
                raise Exception("%s: %s" % (script.name, form.errors))
            script_in_db = form.save(commit=False)
            script_in_db.default = True
            script_in_db.save()
        else:
            if script_in_db.script.data != script_content:
                # Don't add back old versions of a script. This prevents two
                # connected regions with different versions of a script from
                # fighting with eachother.
                no_update = False
                for vtf in script_in_db.script.previous_versions():
                    if vtf.data == script_content:
                        # Don't update anything if we detect we have an old
                        # version of the builtin scripts
                        no_update = True
                        break
                if no_update:
                    continue
                form = ScriptForm(
                    instance=script_in_db,
                    data={
                        "script": script_content,
                        "comment": "Updated by maas-%s" % get_maas_version(),
                    },
                    edit_default=True,
                )
                # Form validation should never fail as these are the scripts
                # which ship with MAAS. If they ever do this will be cause by
                # unit tests.
                if not form.is_valid():
                    raise Exception("%s: %s" % (script.name, form.errors))
                script_in_db = form.save(commit=False)
                script_in_db.default = True
                script_in_db.save()
    def test_update_script(self):
        load_builtin_scripts()
        update_script_values = random.choice(BUILTIN_SCRIPTS)
        script = Script.objects.get(name=update_script_values.name)
        # Fields which we can update
        script.description = factory.make_string()
        script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES)
        script.destructive = not script.destructive
        # Put fake old data in to simulate updating a script.
        old_script = VersionedTextFile.objects.create(
            data=factory.make_string())
        script.script = old_script
        # User changeable fields.
        user_tags = [factory.make_name('tag') for _ in range(3)]
        script.tags = copy.deepcopy(user_tags)
        user_timeout = timedelta(random.randint(0, 1000))
        script.timeout = user_timeout
        script.save()

        load_builtin_scripts()
        script = reload_object(script)

        self.assertEquals(update_script_values.name, script.name)
        self.assertEquals(update_script_values.title, script.title)
        self.assertEquals(update_script_values.description, script.description)
        self.assertEquals("Updated by maas-%s" % get_maas_version(),
                          script.script.comment)
        self.assertEquals(update_script_values.script_type, script.script_type)
        self.assertEquals(update_script_values.destructive, script.destructive)
        self.assertEquals(old_script, script.script.previous_version)
        if script.destructive:
            user_tags.append('destructive')
        self.assertEquals(user_tags, script.tags)
        self.assertEquals(user_timeout, script.timeout)
        self.assertTrue(script.default)
Exemple #3
0
 def register(
     self,
     system_id,
     hostname,
     interfaces,
     url,
     nodegroup_uuid=None,
     beacon_support=False,
     version=None,
 ):
     # Hold off on fabric creation if the remote controller
     # supports beacons; it will happen later when UpdateInterfaces is
     # called.
     create_fabrics = False if beacon_support else True
     result = yield self._register(
         system_id,
         hostname,
         interfaces,
         url,
         nodegroup_uuid=nodegroup_uuid,
         create_fabrics=create_fabrics,
         version=version,
     )
     if beacon_support:
         # The remote supports beaconing, so acknowledge that.
         result["beacon_support"] = True
     if version:
         # The remote supports version checking, so reply to that.
         result["version"] = get_maas_version()
     return result
Exemple #4
0
def get_sys_info():
    """Return basic system information in a dictionary."""
    os_release = get_os_release()
    if "ID" in os_release:
        osystem = os_release["ID"]
    elif "NAME" in os_release:
        osystem = os_release["NAME"]
    else:
        osystem = ""
    if "UBUNTU_CODENAME" in os_release:
        distro_series = os_release["UBUNTU_CODENAME"]
    elif "VERSION_ID" in os_release:
        distro_series = os_release["VERSION_ID"]
    else:
        distro_series = ""
    result = {
        "hostname": socket.gethostname().split(".")[0],
        "architecture": get_architecture(),
        "osystem": osystem,
        "distro_series": distro_series,
        "maas_version": get_maas_version(),
        # In MAAS 2.3+, the NetworksMonitoringService is solely responsible for
        # interface update, because interface updates need to include beaconing
        # data. The key and empty dictionary are necessary for backward
        # compatibility; the region will ignore the empty dictionary in
        # _process_sys_info().
        "interfaces": {},
    }
    return result
Exemple #5
0
def get_sys_info():
    """Return basic system information in a dictionary."""
    os_release = get_os_release()
    if 'ID' in os_release:
        osystem = os_release['ID']
    elif 'NAME' in os_release:
        osystem = os_release['NAME']
    else:
        osystem = ''
    if 'UBUNTU_CODENAME' in os_release:
        distro_series = os_release['UBUNTU_CODENAME']
    elif 'VERSION_ID' in os_release:
        distro_series = os_release['VERSION_ID']
    else:
        distro_series = ''
    result = {
        'hostname': socket.gethostname().split('.')[0],
        'architecture': get_architecture(),
        'osystem': osystem,
        'distro_series': distro_series,
        'maas_version': get_maas_version(),
        # In MAAS 2.3+, the NetworksMonitoringService is solely responsible for
        # interface update, because interface updates need to include beaconing
        # data. The key and empty dictionary are necessary for backward
        # compatibility; the region will ignore the empty dictionary in
        # _process_sys_info().
        'interfaces': {}
    }
    return result
Exemple #6
0
 def test__calls_get_version_from_apt(self):
     mock_apt = self.patch(version, "get_version_from_apt")
     mock_apt.return_value = sentinel.version
     self.expectThat(version.get_maas_version(), Is(sentinel.version))
     self.expectThat(
         mock_apt,
         MockCalledOnceWith(version.RACK_PACKAGE_NAME,
                            version.REGION_PACKAGE_NAME))
def notification_available(notification_version, maas_version=None):
    current_version = version.get_version_tuple(maas_version
                                                or version.get_maas_version())
    log.debug(f"Current MAAS version: {repr(current_version)}")
    log.debug(f"Notification version: {notification_version}")

    notification_version_tuple = version.get_version_tuple(
        notification_version)
    return notification_version_tuple > current_version
Exemple #8
0
 def test_register_acks_version(self):
     yield self.installFakeRegion()
     rack_controller = yield deferToDatabase(factory.make_RackController)
     protocol = self.make_Region()
     protocol.transport = MagicMock()
     response = yield call_responder(
         protocol, RegisterRackController, {
             "system_id": rack_controller.system_id,
             "hostname": rack_controller.hostname,
             "interfaces": {},
             "version": "2.3",
         })
     self.assertThat(response['version'], Equals(get_maas_version()))
Exemple #9
0
def load_builtin_scripts():
    for script in BUILTIN_SCRIPTS:
        script_content = read_text_file(script.script_path)
        try:
            script_in_db = Script.objects.get(name=script.name)
        except Script.DoesNotExist:
            Script.objects.create(name=script.name,
                                  title=script.title,
                                  description=script.description,
                                  tags=script.tags,
                                  script_type=script.script_type,
                                  script=script_content,
                                  comment="Created by maas-%s" %
                                  get_maas_version(),
                                  timeout=script.timeout,
                                  destructive=script.destructive,
                                  default=True)
        else:
            if script_in_db.script.data != script_content:
                # Don't add back old versions of a script. This prevents two
                # connected regions with different versions of a script from
                # fighting with eachother.
                no_update = False
                for vtf in script_in_db.script.previous_versions():
                    if vtf.data == script_content:
                        # Don't update anything if we detect we have an old
                        # version of the builtin scripts
                        no_update = True
                        break
                if no_update:
                    continue
                script_in_db.script = script_in_db.script.update(
                    script_content, "Updated by maas-%s" % get_maas_version())
            script_in_db.title = script.title
            script_in_db.description = script.description
            script_in_db.script_type = script.script_type
            script_in_db.destructive = script.destructive
            script_in_db.save()
    def test_update_script(self):
        load_builtin_scripts()
        update_script_values = random.choice(BUILTIN_SCRIPTS)
        script = Script.objects.get(name=update_script_values.name)

        # Fields which we can update
        orig_title = script.title
        orig_description = script.description
        orig_script_type = script.script_type
        orig_results = script.results
        orig_parameters = script.parameters

        script.title = factory.make_string()
        script.description = factory.make_string()
        script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES)
        script.results = [factory.make_name("result")]
        script.script.parameters = {
            factory.make_name("param"): {
                "type": "storage"
            }
        }

        # Put fake old data in to simulate updating a script.
        old_script = VersionedTextFile.objects.create(
            data=factory.make_string())
        script.script = old_script

        # User changeable fields.
        user_tags = [factory.make_name("tag") for _ in range(3)]
        script.tags = copy.deepcopy(user_tags)
        user_timeout = timedelta(random.randint(0, 1000))
        script.timeout = user_timeout
        script.save()

        load_builtin_scripts()
        script = reload_object(script)

        self.assertEquals(orig_title, script.title, script.name)
        self.assertEquals(orig_description, script.description, script.name)
        self.assertEquals(orig_script_type, script.script_type, script.name)
        self.assertDictEqual(orig_results, script.results, script.name)
        self.assertDictEqual(orig_parameters, script.parameters, script.name)

        self.assertThat(script.tags, ContainsAll(user_tags))
        self.assertEquals(user_timeout, script.timeout)

        self.assertEquals(old_script, script.script.previous_version)
        self.assertEquals("Updated by maas-%s" % get_maas_version(),
                          script.script.comment)
        self.assertTrue(script.default)
    def test_creates_scripts(self):
        load_builtin_scripts()

        for script in BUILTIN_SCRIPTS:
            script_in_db = Script.objects.get(name=script.name)
            self.assertEquals(script.title, script_in_db.title)
            self.assertEquals(script.description, script_in_db.description)
            self.assertEquals("Created by maas-%s" % get_maas_version(),
                              script_in_db.script.comment)
            self.assertItemsEqual(script.tags, script_in_db.tags)
            self.assertEquals(script.script_type, script_in_db.script_type)
            self.assertEquals(script.timeout, script_in_db.timeout)
            self.assertEquals(script.destructive, script_in_db.destructive)
            self.assertTrue(script_in_db.default)
Exemple #12
0
 def test_get_sys_info_empty(self):
     hostname = factory.make_hostname()
     architecture = factory.make_name('architecture')
     self.patch(refresh.socket, 'gethostname').return_value = hostname
     self.patch_autospec(refresh, 'get_os_release').return_value = {}
     self.patch_autospec(
         refresh, 'get_architecture').return_value = architecture
     self.assertThat({
         'hostname': hostname,
         'architecture': architecture,
         'osystem': '',
         'distro_series': '',
         'maas_version': get_maas_version(),
         'interfaces': {},
         }, Equals(refresh.get_sys_info()))
Exemple #13
0
    def test_creates_scripts(self):
        load_builtin_scripts()

        for script in BUILTIN_SCRIPTS:
            script_in_db = Script.objects.get(name=script.name)

            # While MAAS allows user scripts to leave these fields blank,
            # builtin scripts should always have values.
            self.assertTrue(script_in_db.title, script.name)
            self.assertTrue(script_in_db.description, script.name)
            self.assertTrue(script_in_db.script.data, script.name)
            self.assertThat(script_in_db.tags, Not(Equals([])), script.name)

            # These values should always be set by the script loader.
            self.assertEquals("Created by maas-%s" % get_maas_version(),
                              script_in_db.script.comment, script.name)
            self.assertTrue(script_in_db.default, script.name)
Exemple #14
0
 def test_get_sys_info_empty(self):
     hostname = factory.make_hostname()
     architecture = factory.make_name("architecture")
     self.patch(refresh.socket, "gethostname").return_value = hostname
     self.patch_autospec(refresh, "get_os_release").return_value = {}
     self.patch_autospec(refresh,
                         "get_architecture").return_value = architecture
     self.assertThat(
         {
             "hostname": hostname,
             "architecture": architecture,
             "osystem": "",
             "distro_series": "",
             "maas_version": get_maas_version(),
             "interfaces": {},
         },
         Equals(refresh.get_sys_info()),
     )
Exemple #15
0
 def test_get_sys_info_alt(self):
     hostname = factory.make_hostname()
     osystem = factory.make_name('name')
     distro_series = factory.make_name('version_id')
     architecture = factory.make_name('architecture')
     self.patch(refresh.socket, 'gethostname').return_value = hostname
     self.patch_autospec(refresh, 'get_os_release').return_value = {
         'NAME': osystem,
         'VERSION_ID': distro_series,
     }
     self.patch_autospec(
         refresh, 'get_architecture').return_value = architecture
     self.assertThat({
         'hostname': hostname,
         'architecture': architecture,
         'osystem': osystem,
         'distro_series': distro_series,
         'maas_version': get_maas_version(),
         'interfaces': {},
         }, Equals(refresh.get_sys_info()))
Exemple #16
0
 def test_get_sys_info_alt(self):
     hostname = factory.make_hostname()
     osystem = factory.make_name("name")
     distro_series = factory.make_name("version_id")
     architecture = factory.make_name("architecture")
     self.patch(refresh.socket, "gethostname").return_value = hostname
     self.patch_autospec(refresh, "get_os_release").return_value = {
         "NAME": osystem,
         "VERSION_ID": distro_series,
     }
     self.patch_autospec(refresh,
                         "get_architecture").return_value = architecture
     self.assertThat(
         {
             "hostname": hostname,
             "architecture": architecture,
             "osystem": osystem,
             "distro_series": distro_series,
             "maas_version": get_maas_version(),
             "interfaces": {},
         },
         Equals(refresh.get_sys_info()),
     )
Exemple #17
0
 def test__uses_snappy_get_snap_version(self):
     self.patch(snappy, 'running_in_snap').return_value = True
     self.patch(snappy, 'get_snap_version').return_value = sentinel.version
     self.assertEqual(sentinel.version, version.get_maas_version())
    def test_update_doesnt_revert_script(self):
        load_builtin_scripts()
        update_script_index = random.randint(0, len(BUILTIN_SCRIPTS) - 2)
        update_script_values = BUILTIN_SCRIPTS[update_script_index]
        script = Script.objects.get(name=update_script_values.name)
        # Put fake new data in to simulate another MAAS region updating
        # to a newer version.
        new_script = factory.make_string()
        script.script = script.script.update(new_script)

        # Fake user updates
        user_tags = [factory.make_name("tag") for _ in range(3)]
        script.tags = user_tags
        user_timeout = timedelta(random.randint(0, 1000))
        script.timeout = user_timeout
        script.save()

        # Test that subsequent scripts still get updated
        second_update_script_values = BUILTIN_SCRIPTS[update_script_index + 1]
        second_script = Script.objects.get(
            name=second_update_script_values.name)
        # Put fake old data in to simulate updating a script.
        orig_title = second_script.title
        orig_description = second_script.description
        orig_script_type = second_script.script_type
        orig_results = second_script.results
        orig_parameters = second_script.parameters

        second_script.title = factory.make_string()
        second_script.description = factory.make_string()
        second_script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES)
        second_script.results = [factory.make_name("result")]
        second_script.script.parameters = {
            factory.make_name("param"): {
                "type": "storage"
            }
        }

        # Put fake old data in to simulate updating a script.
        old_script = VersionedTextFile.objects.create(
            data=factory.make_string())
        second_script.script = old_script

        second_script.save()

        load_builtin_scripts()

        script = reload_object(script)
        self.assertEquals(update_script_values.name, script.name)
        self.assertEquals(new_script, script.script.data)
        self.assertTrue(min([tag in script.tags for tag in user_tags]))
        self.assertEquals(user_timeout, script.timeout)
        self.assertTrue(script.default)

        second_script = reload_object(second_script)
        self.assertEquals(orig_title, second_script.title)
        self.assertEquals(orig_description, second_script.description)
        self.assertEquals(orig_script_type, second_script.script_type)
        self.assertDictEqual(orig_results, second_script.results)
        self.assertDictEqual(orig_parameters, second_script.parameters)
        self.assertEquals(old_script, second_script.script.previous_version)
        self.assertEquals(
            "Updated by maas-%s" % get_maas_version(),
            second_script.script.comment,
        )
        self.assertTrue(second_script.default)