Beispiel #1
0
 def _print_token(self, token):
     """Write `token` to stdout in the standard format (with names if
     --with-names option is enabled)"""
     if self.display_names:
         self.stdout.write("%s %s" % (convert_tuple_to_string(
             get_creds_tuple(token)), token.consumer.name))
     else:
         self.stdout.write(convert_tuple_to_string(get_creds_tuple(token)))
     # In Django 1.5+, self.stdout.write() adds a newline character at
     # the end of the message.
     if django.VERSION < (1, 5):
         self.stdout.write('\n')
Beispiel #2
0
 def _print_token(self, token):
     """Write `token` to stdout in the standard format."""
     self.stdout.write(convert_tuple_to_string(get_creds_tuple(token)))
     # In Django 1.5+, self.stdout.write() adds a newline character at
     # the end of the message.
     if django.VERSION < (1, 5):
         self.stdout.write('\n')
Beispiel #3
0
 def _print_token(self, token):
     """Write `token` to stdout in the standard format."""
     self.stdout.write(convert_tuple_to_string(get_creds_tuple(token)))
     # In Django 1.5+, self.stdout.write() adds a newline character at
     # the end of the message.
     if django.VERSION < (1, 5):
         self.stdout.write('\n')
Beispiel #4
0
 def _generate_work():
     node_ids = Node.objects.all().values_list("system_id", flat=True)
     node_ids = [{"system_id": node_id} for node_id in node_ids]
     chunked_node_ids = list(chunk_list(node_ids, len(clients)))
     connected_racks = []
     for idx, client in enumerate(clients):
         rack = RackController.objects.get(system_id=client.ident)
         token = _get_or_create_auth_token(rack.owner)
         creds = convert_tuple_to_string(get_creds_tuple(token))
         if len(chunked_node_ids) > idx:
             connected_racks.append({
                 "system_id":
                 rack.system_id,
                 "hostname":
                 rack.hostname,
                 "client":
                 client,
                 "tag_name":
                 tag.name,
                 "tag_definition":
                 tag.definition,
                 "tag_nsmap": [{
                     "prefix": prefix,
                     "uri": uri
                 } for prefix, uri in tag_nsmap.items()],
                 "credentials":
                 creds,
                 "nodes":
                 list(chunked_node_ids[idx]),
             })
     return connected_racks
Beispiel #5
0
 def test_POST_update_nodes_allows_rack_controller(self):
     tag = factory.make_Tag()
     rack_controller = factory.make_RackController()
     node = factory.make_Node()
     client = make_worker_client(rack_controller)
     tokens = list(get_auth_tokens(rack_controller.owner))
     if len(tokens) > 0:
         # Use the latest token.
         token = tokens[-1]
     else:
         token = create_auth_token(rack_controller.owner)
     token.save()
     creds = convert_tuple_to_string(get_creds_tuple(token))
     response = client.post(
         self.get_tag_uri(tag), {
             'op': 'update_nodes',
             'add': [node.system_id],
             'rack_controller': rack_controller.system_id,
             'credentials': creds,
         })
     self.assertEqual(http.client.OK, response.status_code)
     parsed_result = json.loads(
         response.content.decode(settings.DEFAULT_CHARSET))
     self.assertEqual({'added': 1, 'removed': 0}, parsed_result)
     self.assertItemsEqual([node], tag.node_set.all())
Beispiel #6
0
 def test_api_key_rejects_update_without_key_name(self):
     user = factory.make_User()
     existing_token = get_one(user.userprofile.get_authorisation_tokens())
     token_string = convert_tuple_to_string(get_creds_tuple(existing_token))
     error_text = assertCommandErrors(
         self, "apikey", username=user.username, update=token_string
     )
     self.assertIn("Should specify new name", error_text)
 def test_refreshes_api_credentials(self):
     refresh_functions = self.patch_refresh_functions()
     nodegroup = factory.make_node_group()
     refresh_worker(nodegroup)
     creds_string = convert_tuple_to_string(
         get_creds_tuple(nodegroup.api_token))
     self.assertEqual(
         [(creds_string, )],
         refresh_functions['api_credentials'].extract_args())
Beispiel #8
0
 def test_refreshes_api_credentials(self):
     refresh_functions = self.patch_refresh_functions()
     nodegroup = factory.make_node_group()
     refresh_worker(nodegroup)
     creds_string = convert_tuple_to_string(
         get_creds_tuple(nodegroup.api_token))
     self.assertEqual(
         [(creds_string, )],
         refresh_functions['api_credentials'].extract_args())
Beispiel #9
0
 def test_api_key_update_and_generate_mutually_exclusive_options(self):
     user = factory.make_User()
     fake_api_key_name = "Test Key Name"
     existing_token = get_one(
         user.userprofile.get_authorisation_tokens())
     token_string = convert_tuple_to_string(
         get_creds_tuple(existing_token))
     error_text = assertCommandErrors(
         self, 'apikey', username=user.username, generate=True,
         api_key_name=fake_api_key_name, update=token_string)
     self.assertIn("Specify one of --generate or --update.", error_text)
Beispiel #10
0
 def test_success_modify_apikey_name(self):
     stderr = StringIO()
     stdout = StringIO()
     fake_api_key_name = "Test Key Name"
     user = factory.make_User()
     existing_token = get_one(
         user.userprofile.get_authorisation_tokens())
     token_string = convert_tuple_to_string(
         get_creds_tuple(existing_token))
     call_command(
         'apikey', username=user.username, update=token_string,
         api_key_name=fake_api_key_name, stderr=stderr, stdout=stdout)
     self.assertThat(stderr, IsEmpty)
Beispiel #11
0
    def test_apikey_gets_keys(self):
        stderr = StringIO()
        stdout = StringIO()
        user = factory.make_User()
        call_command(
            'apikey', username=user.username, stderr=stderr, stdout=stdout)
        self.assertThat(stderr, IsEmpty)

        expected_token = get_one(
            user.userprofile.get_authorisation_tokens())
        expected_string = convert_tuple_to_string(
            get_creds_tuple(expected_token)) + '\n'
        self.assertEqual(expected_string, stdout.getvalue())
Beispiel #12
0
    def test_apikey_gets_keys(self):
        stderr = BytesIO()
        out = BytesIO()
        stdout = getwriter("UTF-8")(out)
        user = factory.make_user()
        call_command(
            'apikey', username=user.username, stderr=stderr, stdout=stdout)
        self.assertEqual('', stderr.getvalue().strip())

        expected_token = get_one(
            user.get_profile().get_authorisation_tokens())
        expected_string = convert_tuple_to_string(
            get_creds_tuple(expected_token)) + '\n'
        self.assertEqual(expected_string, stdout.getvalue())
Beispiel #13
0
    def test_apikey_deletes_key(self):
        stderr = BytesIO()
        stdout = BytesIO()
        user = factory.make_user()
        existing_token = get_one(
            user.get_profile().get_authorisation_tokens())
        token_string = convert_tuple_to_string(
            get_creds_tuple(existing_token))
        call_command(
            'apikey', username=user.username, delete=token_string,
            stderr=stderr, stdout=stdout)
        self.assertEqual('', stderr.getvalue().strip())

        keys_after = user.get_profile().get_authorisation_tokens()
        self.assertEqual(0, len(keys_after))
Beispiel #14
0
    def test_apikey_deletes_key(self):
        stderr = BytesIO()
        stdout = BytesIO()
        user = factory.make_user()
        existing_token = get_one(user.get_profile().get_authorisation_tokens())
        token_string = convert_tuple_to_string(get_creds_tuple(existing_token))
        call_command('apikey',
                     username=user.username,
                     delete=token_string,
                     stderr=stderr,
                     stdout=stdout)
        self.assertEqual('', stderr.getvalue().strip())

        keys_after = user.get_profile().get_authorisation_tokens()
        self.assertEqual(0, len(keys_after))
Beispiel #15
0
    def test_apikey_gets_keys(self):
        stderr = BytesIO()
        out = BytesIO()
        stdout = getwriter("UTF-8")(out)
        user = factory.make_user()
        call_command('apikey',
                     username=user.username,
                     stderr=stderr,
                     stdout=stdout)
        self.assertEqual('', stderr.getvalue().strip())

        expected_token = get_one(user.get_profile().get_authorisation_tokens())
        expected_string = convert_tuple_to_string(
            get_creds_tuple(expected_token)) + '\n'
        self.assertEqual(expected_string, stdout.getvalue())
Beispiel #16
0
    def test_apikey_deletes_key(self):
        stderr = StringIO()
        stdout = StringIO()
        user = factory.make_User()
        existing_token = get_one(user.userprofile.get_authorisation_tokens())
        token_string = convert_tuple_to_string(get_creds_tuple(existing_token))
        call_command('apikey',
                     username=user.username,
                     delete=token_string,
                     stderr=stderr,
                     stdout=stdout)
        self.assertThat(stderr, IsEmpty)

        keys_after = user.userprofile.get_authorisation_tokens()
        self.assertEqual(0, len(keys_after))
Beispiel #17
0
 def test_prefs_GET_api(self):
     # The preferences page displays the API access tokens.
     user = self.logged_in_user
     # Create a few tokens.
     for i in range(3):
         user.get_profile().create_authorisation_token()
     response = self.client.get('/account/prefs/')
     doc = fromstring(response.content)
     # The OAuth tokens are displayed.
     for token in user.get_profile().get_authorisation_tokens():
         # The token string is a compact representation of the keys.
         self.assertSequenceEqual(
             [convert_tuple_to_string(get_creds_tuple(token))],
             [elem.value.strip() for elem in
                 doc.cssselect('input#%s' % token.key)])
Beispiel #18
0
 def test_prefs_GET_api(self):
     # The preferences page displays the API access tokens.
     user = self.logged_in_user
     # Create a few tokens.
     for i in range(3):
         user.get_profile().create_authorisation_token()
     response = self.client.get('/account/prefs/')
     doc = fromstring(response.content)
     # The OAuth tokens are displayed.
     for token in user.get_profile().get_authorisation_tokens():
         # The token string is a compact representation of the keys.
         self.assertSequenceEqual(
             [convert_tuple_to_string(get_creds_tuple(token))], [
                 elem.value.strip()
                 for elem in doc.cssselect('input#%s' % token.key)
             ])
Beispiel #19
0
 def test_POST_update_nodes_refuses_non_rack_controller(self):
     tag = factory.make_Tag()
     rack_controller = factory.make_RackController()
     node = factory.make_Node()
     token = create_auth_token(rack_controller.owner)
     token.save()
     creds = convert_tuple_to_string(get_creds_tuple(token))
     response = self.client.post(
         self.get_tag_uri(tag), {
             'op': 'update_nodes',
             'add': [node.system_id],
             'rack_controller': rack_controller.system_id,
             'credentials': creds,
         })
     self.assertEqual(http.client.FORBIDDEN, response.status_code)
     self.assertItemsEqual([], tag.node_set.all())
Beispiel #20
0
 def test_apikey_generates_key(self):
     stderr = StringIO()
     stdout = StringIO()
     user = factory.make_User()
     num_keys = len(user.userprofile.get_authorisation_tokens())
     call_command(
         'apikey', username=user.username, generate=True, stderr=stderr,
         stdout=stdout)
     self.assertThat(stderr, IsEmpty)
     keys_after = user.userprofile.get_authorisation_tokens()
     expected_num_keys = num_keys + 1
     self.assertEqual(expected_num_keys, len(keys_after))
     expected_token = user.userprofile.get_authorisation_tokens()[1]
     expected_string = convert_tuple_to_string(
         get_creds_tuple(expected_token)) + '\n'
     self.assertEqual(expected_string, stdout.getvalue())
Beispiel #21
0
    def test_api_key_rejects_deletion_of_nonexistent_key(self):
        stderr = StringIO()
        user = factory.make_User()
        existing_token = get_one(user.userprofile.get_authorisation_tokens())
        token_string = convert_tuple_to_string(get_creds_tuple(existing_token))
        call_command('apikey',
                     username=user.username,
                     delete=token_string,
                     stderr=stderr)
        self.assertThat(stderr, IsEmpty)

        # Delete it again. Check that there's a sensible rejection.
        error_text = assertCommandErrors(self,
                                         'apikey',
                                         username=user.username,
                                         delete=token_string)
        self.assertIn("No matching api key found", error_text)
Beispiel #22
0
 def test_apikey_generates_key(self):
     stderr = BytesIO()
     out = BytesIO()
     stdout = getwriter("UTF-8")(out)
     user = factory.make_user()
     num_keys = len(user.get_profile().get_authorisation_tokens())
     call_command(
         'apikey', username=user.username, generate=True, stderr=stderr,
         stdout=stdout)
     self.assertEqual('', stderr.getvalue().strip())
     keys_after = user.get_profile().get_authorisation_tokens()
     expected_num_keys = num_keys + 1
     self.assertEqual(expected_num_keys, len(keys_after))
     expected_token = user.get_profile().get_authorisation_tokens()[1]
     expected_string = convert_tuple_to_string(
         get_creds_tuple(expected_token)) + '\n'
     self.assertEqual(expected_string, stdout.getvalue())
Beispiel #23
0
 def test_prefs_GET_api(self):
     # The preferences page displays the API access tokens.
     user = factory.make_User()
     self.client.login(user=user)
     # Create a few tokens.
     for _ in range(3):
         user.userprofile.create_authorisation_token()
     response = self.client.get('/account/prefs/')
     doc = fromstring(response.content)
     # The OAuth tokens are displayed.
     for token in user.userprofile.get_authorisation_tokens():
         # The token string is a compact representation of the keys.
         directive = doc.cssselect('li[data-maas-pref-key="%s"]' %
                                   token.key)[0]
         self.assertSequenceEqual(
             [convert_tuple_to_string(get_creds_tuple(token))],
             [elem.value.strip() for elem in directive.cssselect('input')])
Beispiel #24
0
    def test_api_key_rejects_deletion_of_nonexistent_key(self):
        stderr = BytesIO()
        user = factory.make_user()
        existing_token = get_one(
            user.get_profile().get_authorisation_tokens())
        token_string = convert_tuple_to_string(
            get_creds_tuple(existing_token))
        call_command(
            'apikey', username=user.username, delete=token_string,
            stderr=stderr)
        self.assertEqual('', stderr.getvalue().strip())

        # Delete it again. Check that there's a sensible rejection.
        error_text = assertCommandErrors(
            self, 'apikey', username=user.username, delete=token_string)
        self.assertIn(
            "No matching api key found", error_text)
Beispiel #25
0
def refresh_worker(nodegroup):
    """Send worker for `nodegroup` a refresh message with credentials etc.

    This is how we tell the worker its MAAS API credentials, the name of
    the node group it manages, and so on.  The function gathers all the
    usual information (although we can always extend the mechanism with
    more specific knowledge that we may choose not to include here) and
    issues a task to the node-group worker that causes it to absorb the
    given information items.
    """

    items = {
        'api_credentials': convert_tuple_to_string(
            get_creds_tuple(nodegroup.api_token)),
        'nodegroup_uuid': nodegroup.uuid,
    }

    refresh_secrets.apply_async(queue=nodegroup.work_queue, kwargs=items)
Beispiel #26
0
def populate_tags(tag):
    """Evaluate `tag` for all nodes.

    This returns a `Deferred` that will fire when all tags have been
    evaluated. The return value is intended FOR TESTING ONLY because:

    - You must not use the `Deferred` in the calling thread; it must only be
      manipulated in the reactor thread. Pretending it's not there is safer
      than chaining code onto it because it's easy to get wrong.

    - The call may not finish for 10 minutes or more. It is therefore not a
      good thing to be waiting for in a web request.

    """
    logger.debug('Evaluating the "%s" tag for all nodes.', tag.name)
    clients = getAllClients()
    if len(clients) == 0:
        # We have no clients so we need to do the work locally.
        return populate_tag_for_multiple_nodes(tag, Node.objects.all())
    else:
        # Split the work between the connected rack controllers.
        node_ids = Node.objects.all().values_list("system_id", flat=True)
        node_ids = [{"system_id": node_id} for node_id in node_ids]
        chunked_node_ids = list(chunk_list(node_ids, len(clients)))
        connected_racks = []
        for idx, client in enumerate(clients):
            rack = RackController.objects.get(system_id=client.ident)
            token = _get_or_create_auth_token(rack.owner)
            creds = convert_tuple_to_string(get_creds_tuple(token))
            if len(chunked_node_ids) > idx:
                connected_racks.append({
                    "system_id": rack.system_id,
                    "hostname": rack.hostname,
                    "client": client,
                    "tag_name": tag.name,
                    "tag_definition": tag.definition,
                    "tag_nsmap": [
                        {"prefix": prefix, "uri": uri}
                        for prefix, uri in tag_nsmap.items()
                    ],
                    "credentials": creds,
                    "nodes": list(chunked_node_ids[idx]),
                })
        return _do_populate_tags(connected_racks)
Beispiel #27
0
 def test_apikey_generates_key(self):
     stderr = BytesIO()
     out = BytesIO()
     stdout = getwriter("UTF-8")(out)
     user = factory.make_user()
     num_keys = len(user.get_profile().get_authorisation_tokens())
     call_command('apikey',
                  username=user.username,
                  generate=True,
                  stderr=stderr,
                  stdout=stdout)
     self.assertEqual('', stderr.getvalue().strip())
     keys_after = user.get_profile().get_authorisation_tokens()
     expected_num_keys = num_keys + 1
     self.assertEqual(expected_num_keys, len(keys_after))
     expected_token = user.get_profile().get_authorisation_tokens()[1]
     expected_string = convert_tuple_to_string(
         get_creds_tuple(expected_token)) + '\n'
     self.assertEqual(expected_string, stdout.getvalue())
Beispiel #28
0
def refresh_worker(nodegroup):
    """Send worker for `nodegroup` a refresh message with credentials etc.

    This is how we tell the worker its MAAS API credentials, the name of
    the node group it manages, and so on.  The function gathers all the
    usual information (although we can always extend the mechanism with
    more specific knowledge that we may choose not to include here) and
    issues a task to the node-group worker that causes it to absorb the
    given information items.
    """

    items = {
        'api_credentials':
        convert_tuple_to_string(get_creds_tuple(nodegroup.api_token)),
        'nodegroup_uuid':
        nodegroup.uuid,
    }
    refresh_secrets.apply_async(queue=nodegroup.work_queue, kwargs=items)
    refresh_secrets.apply_async(queue='master', kwargs=items)
Beispiel #29
0
 def test_POST_update_nodes_refuses_no_token(self):
     tag = factory.make_Tag()
     rack_controller = factory.make_RackController()
     node = factory.make_Node()
     # create a token for a different user
     token = create_auth_token(factory.make_User())
     token.save()
     creds = convert_tuple_to_string(get_creds_tuple(token))
     response = self.client.post(
         self.get_tag_uri(tag),
         {
             "op": "update_nodes",
             "add": [node.system_id],
             "rack_controller": rack_controller.system_id,
             "credentials": creds,
         },
     )
     self.assertEqual(http.client.FORBIDDEN, response.status_code)
     self.assertItemsEqual([], tag.node_set.all())
Beispiel #30
0
    def test_api_key_rejects_update_of_nonexistent_key(self):
        stderr = StringIO()
        user = factory.make_User()
        fake_api_key_name = "Test Key Name"
        existing_token = get_one(user.userprofile.get_authorisation_tokens())
        token_string = convert_tuple_to_string(get_creds_tuple(existing_token))
        call_command('apikey',
                     username=user.username,
                     delete=token_string,
                     stderr=stderr)
        self.assertThat(stderr, IsEmpty)

        # Try to update the deleted token.
        error_text = assertCommandErrors(self,
                                         'apikey',
                                         username=user.username,
                                         update=token_string,
                                         api_key_name=fake_api_key_name)
        self.assertIn("No matching api key found", error_text)
Beispiel #31
0
    def test_calls_are_made_to_all_clusters(self):
        rpc_fixture = self.prepare_live_rpc()
        rack_controllers = [factory.make_RackController() for _ in range(3)]
        protocols = []
        rack_creds = []
        for rack in rack_controllers:
            tokens = list(get_auth_tokens(rack.owner))
            if len(tokens) > 0:
                # Use the latest token.
                token = tokens[-1]
            else:
                token = create_auth_token(rack.owner)
            creds = convert_tuple_to_string(get_creds_tuple(token))
            rack_creds.append(creds)

            protocol = rpc_fixture.makeCluster(rack, EvaluateTag)
            protocol.EvaluateTag.side_effect = always_succeed_with({})
            protocols.append(protocol)
        tag = factory.make_Tag(populate=False)

        [d] = populate_tags(tag)

        # `d` is a testing-only convenience. We must wait for it to fire, and
        # we must do that from the reactor thread.
        wait_for_populate = asynchronous(lambda: d)
        wait_for_populate().wait(10)

        for rack, protocol, creds in zip(rack_controllers, protocols,
                                         rack_creds):
            self.expectThat(
                protocol.EvaluateTag,
                MockCalledOnceWith(
                    protocol,
                    tag_name=tag.name,
                    tag_definition=tag.definition,
                    system_id=rack.system_id,
                    tag_nsmap=ANY,
                    credentials=creds,
                    nodes=ANY,
                ),
            )
Beispiel #32
0
 def test_get_creds_tuple_integrates_with_api_client(self):
     creds_tuple = get_creds_tuple(create_auth_token(factory.make_user()))
     self.assertEqual(
         creds_tuple,
         convert_string_to_tuple(convert_tuple_to_string(creds_tuple)))
Beispiel #33
0
 def test_get_creds_tuple_returns_creds(self):
     token = create_auth_token(factory.make_user())
     self.assertEqual((token.consumer.key, token.key, token.secret),
                      get_creds_tuple(token))
Beispiel #34
0
 def test_get_creds_tuple_integrates_with_api_client(self):
     creds_tuple = get_creds_tuple(create_auth_token(factory.make_user()))
     self.assertEqual(
         creds_tuple,
         convert_string_to_tuple(convert_tuple_to_string(creds_tuple)))
Beispiel #35
0
 def test_get_creds_tuple_returns_creds(self):
     token = create_auth_token(factory.make_user())
     self.assertEqual(
         (token.consumer.key, token.key, token.secret),
         get_creds_tuple(token))