コード例 #1
0
def main():
    module = AnsibleModule(argument_spec=dict(
        maas=dict(default='http://localhost/MAAS/api/1.0/'),
        key=dict(required=True),
        state=dict(default='query', choices=['query', 'import'])),
                           supports_check_mode=False)

    maas = module.params['maas']
    key = module.params['key']
    state = module.params['state']

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    if state == 'query':
        res = maas.get('/boot-resources/')
        if res.ok:
            module.exit_json(changed=False, resources=json.loads(res.text))
        else:
            module.fail_json(msg=string_or_object(res.text))
    elif state == 'import':
        res = maas.post('/boot-resources/', dict(op='import'))
        if res.ok:
            module.exit_json(changed=True)
        else:
            module.fail_json(msg=string_or_object(res.text))
    else:
        module.fail_json(msg='unknown state')
コード例 #2
0
ファイル: maas_boot_resource.py プロジェクト: opencord/maas
def main():
    module = AnsibleModule(
        argument_spec = dict(
            maas=dict(default='http://localhost/MAAS/api/1.0/'),
            key=dict(required=True),
            state=dict(default='query', choices=['query', 'import'])
        ),
        supports_check_mode = False
    )

    maas = module.params['maas']
    key = module.params['key']
    state = module.params['state']

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    if state == 'query':
        res = maas.get('/boot-resources/')
        if res.ok:
            module.exit_json(changed=False, resources=json.loads(res.text))
        else:
            module.fail_json(msg=string_or_object(res.text))
    elif state == 'import':
        res = maas.post('/boot-resources/', dict(op='import'))
        if res.ok:
            module.exit_json(changed=True)
        else:
            module.fail_json(msg=string_or_object(res.text))
    else:
        module.fail_json(msg='unknown state')
コード例 #3
0
    def test_tag_name(self, mock_requests, mock_oauth):

        system_id = "node-01"

        with patch("maasclient.MaasClient.tag_new") as mock_tag_new:
            with patch("maasclient.MaasClient.tag_machine") as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_name(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(system_id)
                mock_tag_mach.assert_called_once_with(system_id, system_id)
コード例 #4
0
    def test_tag_fpi(self, mock_requests, mock_oauth):

        system_id = "node-01"
        fpi_tag = "use-fastpath-installer"

        with patch("maasclient.MaasClient.tag_new") as mock_tag_new:
            with patch("maasclient.MaasClient.tag_machine") as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_fpi(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(fpi_tag)
                mock_tag_mach.assert_called_once_with(fpi_tag, system_id)
コード例 #5
0
    def test_tag_name(self, mock_requests, mock_oauth):

        system_id = "node-01"

        with patch('maasclient.MaasClient.tag_new') as mock_tag_new:
            with patch('maasclient.MaasClient.tag_machine') as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_name(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(system_id)
                mock_tag_mach.assert_called_once_with(system_id,
                                                      system_id)
コード例 #6
0
class MaasClientZoneTest(unittest.TestCase):
    def setUp(self):
        self.c = MaasClient(AUTH)
        self.zone_name = 'testzone-' + str(uuid.uuid1())
        res = self.c.zone_new(self.zone_name, 'zone created in unittest')
        self.assertTrue(res)

    def tearDown(self):
        res = self.c.zone_delete(self.zone_name)
        self.assertTrue(res)

    def test_get_zones(self):
        self.assertTrue(self.zone_name in [z['name'] for z in self.c.zones])
コード例 #7
0
    def test_tag_fpi(self, mock_requests, mock_oauth):

        system_id = "node-01"
        fpi_tag = 'use-fastpath-installer'

        with patch('maasclient.MaasClient.tag_new') as mock_tag_new:
            with patch('maasclient.MaasClient.tag_machine') as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_fpi(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(fpi_tag)
                mock_tag_mach.assert_called_once_with(fpi_tag,
                                                      system_id)
コード例 #8
0
class MaasClientTest(unittest.TestCase):
    def setUp(self):
        self.c = MaasClient(AUTH)
        self.tag = 'a-test-tag-' + str(uuid.uuid1())
        res = self.c.tag_new(self.tag)
        self.assertTrue(res)

    def tearDown(self):
        res = self.c.tag_delete(self.tag)
        self.assertTrue(res)

    def test_get_tags(self):
        self.assertTrue(self.tag in [t['name'] for t in self.c.tags])
コード例 #9
0
class MaasClientTest(unittest.TestCase):
    def setUp(self):
        self.c = MaasClient(AUTH)
        self.tag = 'a-test-tag-' + str(uuid.uuid1())
        res = self.c.tag_new(self.tag)
        self.assertTrue(res)

    def tearDown(self):
        res = self.c.tag_delete(self.tag)
        self.assertTrue(res)

    def test_get_tags(self):
        self.assertTrue(self.tag in [t['name'] for t in self.c.tags])
コード例 #10
0
ファイル: list_nodes.py プロジェクト: tinycolds/maasclient
def main():
    url = None
    if len(sys.argv) == 3:
        url = sys.argv[1]
        key = sys.argv[2]
        auth = MaasAuth(api_url=url, api_key=key)
    else:
        auth = MaasAuth(api_url=url)
        auth.get_api_key('root')
    maas_client = MaasClient(auth)
    pprint.pprint(maas_client.nodes)
    pprint.pprint(maas_client.get_server_config('maas_name'))
    pprint.pprint(maas_client.server_hostname)
コード例 #11
0
class MaasClientZoneTest(unittest.TestCase):
    def setUp(self):
        self.c = MaasClient(AUTH)
        self.zone_name = 'testzone-' + str(uuid.uuid1())
        res = self.c.zone_new(self.zone_name,
                              'zone created in unittest')
        self.assertTrue(res)

    def tearDown(self):
        res = self.c.zone_delete(self.zone_name)
        self.assertTrue(res)

    def test_get_zones(self):
        self.assertTrue(self.zone_name in [z['name'] for z in self.c.zones])
コード例 #12
0
ファイル: maas_sshkey.py プロジェクト: pan2za/maas
def main():
    module = AnsibleModule(argument_spec=dict(
        maas=dict(default='http://localhost/MAAS/api/1.0/'),
        key=dict(required=True),
        sshkey=dict(required=True),
        state=dict(default='present', choices=['present', 'absent', 'query'])),
                           supports_check_mode=False)

    maas = module.params['maas']
    key = module.params['key']
    state = module.params['state']

    # Construct a sparsely populate desired state
    desired = remove_null({
        'key': module.params['sshkey'],
    })

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    # Attempt to get the item from MAAS
    sshkey = get_sshkey(maas, desired['key'])

    # Actions if the item does not currently exist
    if not sshkey:
        if state == 'query':
            # If this is a query, return it is not found
            module.exit_json(changed=False, found=False)
        elif state == 'present':
            # If this should be present, then attempt to create it
            res = create_sshkey(maas, desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True, sshkey=res['status'])
        else:
            # If this should be absent, then we are done and in the desired state
            module.exit_json(changed=False)

        # Done with items does not exists actions
        return

    # Actions if the item does exist
    if state == 'query':
        # If this is a query, return the sshkey
        module.exit_json(changed=False, found=True, sshkey=sshkey)
    elif state == 'present':
        # If we want this to exists check to see if this is different and
        # needs updated
        # No differences, to nothing to change
        module.exit_json(changed=False, sshkey=sshkey)
    else:
        # If we don't want this item, then delete it
        res = delete_sshkey(maas, item['id'])
        if res['error']:
            module.fail_json(msg=res['status'])
        else:
            module.exit_json(changed=True, sshkey=sshkey)
コード例 #13
0
def main():
    url = None
    if len(sys.argv) > 1:
        url = sys.argv[1]
    auth = MaasAuth(api_url=url)
    auth.get_api_key('root')
    maas_client = MaasClient(auth)

    pprint.pprint(maas_client.nodes)
コード例 #14
0
def connect_to_maas(creds=None):
    if creds:
        api_host = creds['api_host']
        api_url = 'http://{}/MAAS/api/1.0'.format(api_host)
        api_key = creds['api_key']
        auth = MaasAuth(api_url=api_url, api_key=api_key)
    else:
        auth = MaasAuth()
        auth.get_api_key('root')
    maas = MaasClient(auth)
    maas_state = MaasState(maas)
    return maas, maas_state
コード例 #15
0
 def setUp(self):
     self.mock_auth = MagicMock()
     self.api_url = 'apiurl'
     url_p = PropertyMock(return_value=self.api_url)
     type(self.mock_auth).api_url = url_p
     self.c = MaasClient(self.mock_auth)
コード例 #16
0
class MaasClientTagTest(unittest.TestCase):
    def setUp(self):
        self.mock_auth = MagicMock()
        self.api_url = 'apiurl'
        url_p = PropertyMock(return_value=self.api_url)
        type(self.mock_auth).api_url = url_p
        self.c = MaasClient(self.mock_auth)

    def test_get_no_tags(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, ok=True, response="[]")
        self.assertEqual(self.c.tags, [])

    def test_get_tags(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, ok=True,
                            response=TWO_TAGS_JSON)
        self.assertEqual(self.c.tags[0]['name'], 'tag1')
        self.assertEqual(self.c.tags[1]['name'], 'tag2')

    def test_create_tag_existing(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, op='get', ok=True,
                            response=TWO_TAGS_JSON)
        setup_mock_response(mock_requests, op='post', ok=True)
        rv = self.c.tag_new('tag1')
        self.assertEqual(rv, False)
        self.assertEqual(mock_requests.post.call_count, 0)

    def test_create_tag_nonexisting(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, op='get', ok=True,
                            response=TWO_TAGS_JSON)
        setup_mock_response(mock_requests, op='post', ok=True)

        mock_oauth.return_value = sentinel.OAUTH

        newtag = 'newtag'
        rv = self.c.tag_new(newtag)
        self.assertEqual(True, rv)
        mock_requests.post.assert_called_once_with(url=self.api_url + '/tags/',
                                                   auth=sentinel.OAUTH,
                                                   data=dict(op='new',
                                                             name=newtag))

    def test_tag_name(self, mock_requests, mock_oauth):

        system_id = "node-01"

        with patch('maasclient.MaasClient.tag_new') as mock_tag_new:
            with patch('maasclient.MaasClient.tag_machine') as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_name(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(system_id)
                mock_tag_mach.assert_called_once_with(system_id,
                                                      system_id)

    def test_tag_fpi(self, mock_requests, mock_oauth):

        system_id = "node-01"
        fpi_tag = 'use-fastpath-installer'

        with patch('maasclient.MaasClient.tag_new') as mock_tag_new:
            with patch('maasclient.MaasClient.tag_machine') as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_fpi(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(fpi_tag)
                mock_tag_mach.assert_called_once_with(fpi_tag,
                                                      system_id)
コード例 #17
0
 def setUp(self):
     self.c = MaasClient(AUTH)
     self.tag = 'a-test-tag-' + str(uuid.uuid1())
     res = self.c.tag_new(self.tag)
     self.assertTrue(res)
コード例 #18
0
 def setUp(self):
     self.c = MaasClient(AUTH)
     self.zone_name = 'testzone-' + str(uuid.uuid1())
     res = self.c.zone_new(self.zone_name, 'zone created in unittest')
     self.assertTrue(res)
コード例 #19
0
def main():
    module = AnsibleModule(argument_spec=dict(
        maas=dict(default='http://localhost/MAAS/api/1.0/'),
        key=dict(required=True),
        base=dict(required=False),
        cluster_name=dict(required=True),
        name=dict(required=True),
        interface=dict(required=False),
        ip=dict(required=False),
        subnet_mask=dict(required=False),
        management=dict(default='unmanaged',
                        choices=['unmanaged', 'dhcp', 'dhcpdns']),
        ip_range_low=dict(required=False),
        ip_range_high=dict(required=False),
        static_ip_range_low=dict(required=False),
        static_ip_range_high=dict(required=False),
        broadcast_ip=dict(required=False),
        router_ip=dict(required=False),
        state=dict(default='present', choices=['present', 'absent', 'query'])),
                           supports_check_mode=False)

    maas = module.params['maas']
    key = module.params['key']
    state = module.params['state']

    management_map = {'unmanaged': 0, 'dhcp': 1, 'dhcpdns': 2}

    # Construct a sparsely populate desired state
    desired = remove_null({
        'name':
        module.params['name'],
        'interface':
        module.params['interface'],
        'ip':
        module.params['ip'],
        'subnet_mask':
        module.params['subnet_mask'],
        'management':
        management_map[module.params['management']],
        'ip_range_low':
        module.params['ip_range_low'],
        'ip_range_high':
        module.params['ip_range_high'],
        'static_ip_range_low':
        module.params['static_ip_range_low'],
        'static_ip_range_high':
        module.params['static_ip_range_high'],
        'broadcast_ip':
        module.params['broadcast_ip'],
        'router_ip':
        module.params['router_ip'],
    })

    debug = []

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    # Attempt to locate the cluster on which we will be working, error out if it can't be found
    cluster = get_cluster(maas, module.params['cluster_name'])
    if not cluster:
        module.fail_json(
            msg='Unable to find specified cluster "%s", cannot continue' %
            module.params['cluster_name'])
        return

    debug.append({"desired": desired})

    # Attempt to get the cluster interface from MAAS
    cluster_interface = get_cluster_interface(maas, cluster, desired['name'])

    debug.append({"found": cluster_interface})

    # Actions if the cluster interface does not currently exist
    if not cluster_interface:
        if state == 'query':
            # If this is a query, returne it is not found
            module.exit_json(changed=False, found=False)
        elif state == 'present':
            # If this should be present, then attempt to create it
            res = create_cluster_interface(maas, cluster, desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True,
                                 cluster_interface=res['status'],
                                 debug=debug)
        else:
            # If this should be absent, then we are done and in the desired state
            module.exit_json(changed=False)

        # Done with cluster interfaces does not exists actions
        return

    # Actions if the cluster interface does exist
    if state == 'query':
        # If this is a query, return the cluster interface
        module.exit_json(changed=False,
                         found=True,
                         cluster_interface=cluster_interface)
    elif state == 'present':
        # If we want this to exists check to see if this is different and
        # needs updated
        if different(cluster_interface, desired, debug):
            res = update_cluster_interface(maas, cluster, cluster_interface,
                                           desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True,
                                 cluster_interface=res['status'],
                                 debug=debug)
        else:
            # No differences, to nothing to change
            module.exit_json(changed=False,
                             cluster_interface=cluster_interface)
    else:
        # If we don't want this cluster interface, then delete it
        res = delete_cluster_interface(maas, cluster,
                                       cluster_interface['name'])
        if res['error']:
            module.fail_json(msg=res['status'])
        else:
            module.exit_json(changed=True, cluster_interface=cluster_interface)
コード例 #20
0
class MaasClientTagTest(unittest.TestCase):
    def setUp(self):
        self.mock_auth = MagicMock()
        self.api_url = "apiurl"
        url_p = PropertyMock(return_value=self.api_url)
        type(self.mock_auth).api_url = url_p
        self.c = MaasClient(self.mock_auth)

    def test_get_no_tags(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, ok=True, response="[]")
        self.assertEqual(self.c.tags, [])

    def test_get_tags(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, ok=True, response=TWO_TAGS_JSON)
        self.assertEqual(self.c.tags[0]["name"], "tag1")
        self.assertEqual(self.c.tags[1]["name"], "tag2")

    def test_create_tag_existing(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, op="get", ok=True, response=TWO_TAGS_JSON)
        setup_mock_response(mock_requests, op="post", ok=True)
        rv = self.c.tag_new("tag1")
        self.assertEqual(rv, False)
        self.assertEqual(mock_requests.post.call_count, 0)

    def test_create_tag_nonexisting(self, mock_requests, mock_oauth):
        setup_mock_response(mock_requests, op="get", ok=True, response=TWO_TAGS_JSON)
        setup_mock_response(mock_requests, op="post", ok=True)

        mock_oauth.return_value = sentinel.OAUTH

        newtag = "newtag"
        rv = self.c.tag_new(newtag)
        self.assertEqual(True, rv)
        mock_requests.post.assert_called_once_with(
            url=self.api_url + "/tags/", auth=sentinel.OAUTH, data=dict(op="new", name=newtag)
        )

    def test_tag_name(self, mock_requests, mock_oauth):

        system_id = "node-01"

        with patch("maasclient.MaasClient.tag_new") as mock_tag_new:
            with patch("maasclient.MaasClient.tag_machine") as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_name(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(system_id)
                mock_tag_mach.assert_called_once_with(system_id, system_id)

    def test_tag_fpi(self, mock_requests, mock_oauth):

        system_id = "node-01"
        fpi_tag = "use-fastpath-installer"

        with patch("maasclient.MaasClient.tag_new") as mock_tag_new:
            with patch("maasclient.MaasClient.tag_machine") as mock_tag_mach:
                c = MaasClient(self.mock_auth)
                c.tag_fpi(json.loads(ONE_MACHINE_JSON_NOTAGS))

                mock_tag_new.assert_called_once_with(fpi_tag)
                mock_tag_mach.assert_called_once_with(fpi_tag, system_id)
コード例 #21
0
def main():
    module = AnsibleModule(argument_spec=dict(
        maas=dict(default='http://localhost/MAAS/api/1.0/'),
        key=dict(required=True),
        name=dict(required=True),
        email=dict(required=False),
        password=dict(required=False),
        is_superuser=dict(default=False, type='bool'),
        state=dict(default='present', choices=['present', 'absent', 'query'])),
                           supports_check_mode=False)

    maas = module.params['maas']
    key = module.params['key']
    state = module.params['state']

    # Construct a sparsely populate desired state
    desired = remove_null({
        'username':
        module.params['name'],
        'email':
        module.params['email'],
        'password':
        module.params['password'],
        'is_superuser':
        0 if not module.params['is_superuser'] else 1
    })

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    # Attempt to get the user from MAAS
    user = get_user(maas, desired['username'])

    # Actions if the user does not currently exist
    if not user:
        if state == 'query':
            # If this is a query, returne it is not found
            module.exit_json(changed=False, found=False)
        elif state == 'present':
            # If this should be present, then attempt to create it
            res = create_user(maas, desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True, user=res['status'])
        else:
            # If this should be absent, then we are done and in the desired state
            module.exit_json(changed=False)

        # Done with users does not exists actions
        return

    # Actions if the user does exist
    if state == 'query':
        # If this is a query, return the user
        module.exit_json(changed=False, found=True, user=user)
    elif state == 'present':
        # If we want this to exists check to see if this is different and
        # needs updated
        if different(user, desired):
            module.fail_json(
                msg=
                'Specified user, "%s", exists and MAAS does not allow the user to be modified programatically'
                % user['username'])
        else:
            # No differences, to nothing to change
            module.exit_json(changed=False, user=user)
    else:
        # If we don't want this user, then delete it
        res = delete_user(maas, user['username'])
        if res['error']:
            module.fail_json(msg=res['status'])
        else:
            module.exit_json(changed=True, user=user)
コード例 #22
0
def main():
    parser = OptionParser()
    parser.add_option('-c', '--config', dest='config_file',
        help="specifies file from which configuration should be read", metavar='FILE')
    parser.add_option('-a', '--apikey', dest='apikey',
        help="specifies the API key to use when accessing MAAS")
    parser.add_option('-u', '--url', dest='url', default='http://localhost/MAAS/api/1.0',
        help="specifies the URL on which to contact MAAS")
    parser.add_option('-z', '--zone', dest='zone', default='administrative',
        help="specifies the zone to create for manually managed hosts")
    parser.add_option('-i', '--interface', dest='interface', default='eth0:1',
        help="the interface on which to set up DHCP for POD local hosts")
    parser.add_option('-n', '--network', dest='network', default='10.0.0.0/16',
        help="subnet to use for POD local DHCP")
    parser.add_option('-b', '--bridge', dest='bridge', default='mgmtbr',
        help="bridge to use for host local VM allocation")
    parser.add_option('-t', '--bridge-subnet', dest='bridge_subnet', default='172.18.0.0/16',
        help="subnet to assign from for bridged hosts")
    parser.add_option('-r', '--cluster', dest='cluster', default='Cluster master',
        help="name of cluster to user for POD / DHCP")
    parser.add_option('-s', '--sshkey', dest='sshkey', default=None,
        help="specifies public ssh key")
    parser.add_option('-d', '--domain', dest='domain', default='cord.lab',
        help="specifies the domain to configure in maas")
    parser.add_option('-g', '--gateway', dest='gw', default=None,
        help="specifies the gateway to configure for servers")
    (options, args) = parser.parse_args()

    if len(args) > 0:
        print("unknown command line arguments specified", file=sys.stderr)
        parser.print_help()
        sys.exit(1)

    # If a config file was specified then read the config from that
    config = {}
    if options.config_file != None:
        with open(options.config_file) as config_file:
            config = json.load(config_file)

    # Override the config with any command line options
    if options.apikey == None:
        print("must specify a  MAAS API key", file=sys.stderr)
        sys.exit(1)
    else:
        config['key'] = options.apikey
    if options.url != None:
        config['url'] = options.url
    if options.zone != None:
        config['zone'] = options.zone
    if options.interface != None:
        config['interface'] = options.interface
    if options.network != None:
        config['network'] = options.network
    if options.bridge != None:
        config['bridge'] = options.bridge
    if options.bridge_subnet != None:
        config['bridge-subnet'] = options.bridge_subnet
    if options.cluster != None:
        config['cluster'] = options.cluster
    if options.domain != None:
        config['domain'] = options.domain
    if options.gw != None:
        config['gw'] = options.gw
    if not 'gw' in config.keys():
        config['gw'] = None
    if options.sshkey == None:
        print("must specify a SSH key to use for cord user", file=sys.stderr)
        sys.exit(1)
    else:
        config['sshkey'] = options.sshkey
    
    auth = MaasAuth(config['url'], config['key'])
    client = MaasClient(auth)

    resp = client.get('/account/prefs/sshkeys/', dict(op='list'))
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to query SSH keys from server '%d : %s'"
	        % (resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    found_key = False
    keys = json.loads(resp.text)
    for key in keys:
	if key['key'] == config['sshkey']:
	    print("INFO: specified SSH key already exists")
            found_key = True

    # Add the SSH key to the user
    # POST /api/2.0/account/prefs/sshkeys/ op=new
    if not found_key:
        resp = client.post('/account/prefs/sshkeys/', dict(op='new', key=config['sshkey']))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to add sshkey for user: '******'"
                    % (resp.status_code, resp.text), file=sys.stderr)
            sys.exit(1)
	else:
	    print("CHANGED: updated ssh key")
    
    # Check to see if an "administrative" zone exists and if not
    # create one
    found = None
    zones = client.zones
    for zone in zones:
        if zone['name'] == config['zone']:
            found=zone
    
    if found is not None:
        print("INFO: administrative zone, '%s', already exists" % config['zone'], file=sys.stderr)
    else:
        if not client.zone_new(config['zone'], "Zone for manually administrated nodes"):
            print("ERROR: unable to create administrative zone '%s'" % config['zone'], file=sys.stderr)
            sys.exit(1)
        else:
            print("CHANGED: Zone '%s' created" % config['zone'])
    
    # If the interface doesn't already exist in the cluster then
    # create it. Look for the "Cluster Master" node group, but
    # if it is not found used the first one in the list, if the
    # list is empty, error out
    found = None
    ngs = client.nodegroups
    for ng in ngs:
        if ng['cluster_name'] == config['cluster']:
            found = ng
            break
    
    if found is None:
        print("ERROR: unable to find cluster with specified name, '%s'" % config['cluster'], file=sys.stderr)
        sys.exit(1)

    resp = client.get('/nodegroups/' + ng['uuid'] + '/', dict())
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to get node group information for cluster '%s': '%d : %s'"
	    % (config['cluster'], resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    data = json.loads(resp.text)
    
    # Set the DNS domain name (zone) for the cluster
    if data['name'] != config['domain']:
        resp = put(client, '/nodegroups/' + ng['uuid'] + '/', dict(name=config['domain']))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to set the DNS domain name for the cluster with specified name, '%s': '%d : %s'"
                % (config['cluster'], resp.status_code, resp.text), file=sys.stderr)
	    sys.exit(1)
        else:
            print("CHANGE: updated name of cluster to '%s' : %s" % (config['domain'], resp))
    else:
        print("INFO: domain name already set")
    
    found = None
    resp = client.get('/nodegroups/' + ng['uuid'] + '/interfaces/', dict(op='list'))
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to fetch interfaces for cluster with specified name, '%s': '%d : %s'"
            % (config['cluster'], resp.status_code, resp.text), file=sys.stderr)
        sys.exit(1)
    ifcs = json.loads(resp.text)

    localIfc = hostIfc = None 
    for ifc in ifcs:
        localIfc = ifc if ifc['name'] == config['interface'] else localIfc
        hostIfc = ifc if ifc['name'] == config['bridge'] else hostIfc

    add_or_update_node_group_interface(client, ng, config['gw'], localIfc, config['interface'], config['network'])
    add_or_update_node_group_interface(client, ng, config['gw'], hostIfc, config['bridge'], config['bridge-subnet'])

    # Update the server settings to upstream DNS request to Google
    # POST /api/2.0/maas/ op=set_config
    resp = client.get('/maas/', dict(op='get_config', name='upstream_dns'))
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to get the upstream DNS servers: '%d : %s'"
              % (resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    if unicode(json.loads(resp.text)) != u'8.8.8.8 8.8.8.4':
        resp = client.post('/maas/', dict(op='set_config', name='upstream_dns', value='8.8.8.8 8.8.8.4'))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to set the upstream DNS servers: '%d : %s'"
                % (resp.status_code, resp.text), file=sys.stderr)
        else:
            print("CHANGED: updated up stream DNS servers")
    else:
        print("INFO: Upstream DNS servers correct")

    # Start the download of boot images
    resp = client.get('/boot-resources/', None)
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to read existing images download: '%d : %s'" % (resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    imgs = json.loads(resp.text)
    found = False
    for img in imgs:
	if img['name'] == u'ubuntu/trusty' and img['architecture'] == u'amd64/hwe-t':
	    found = True

    if not found:
        resp = client.post('/boot-resources/', dict(op='import'))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to start image download: '%d : %s'" % (resp.status_code, resp.text), file=sys.stderr)
	    sys.exit(1)
        else:
            print("CHANGED: Image download started")
    else:
	print("INFO: required images already available")
コード例 #23
0
def main():
    module = AnsibleModule(
        argument_spec = dict(
            maas=dict(default='http://localhost/MAAS/api/1.0/'),
            key=dict(required=True),
            name=dict(required=True),
            status=dict(default='enabled', choices=['enabled', 'disabled']),
            domain=dict(required=False),
            state=dict(default='present', choices=['present', 'query'])
        ),
        supports_check_mode = False
    )

    maas = module.params['maas']
    key = module.params['key']
    state = module.params['state']

    status_map = {
        'enabled': 1,
        'disabled': 2
    }

    # Construct a sparsely populate desired state
    desired = remove_null({
        'cluster_name': module.params['name'],
        'status': status_map[module.params['status']],
        'name' : module.params['domain'],
    })

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    # Attempt to get the cluster from MAAS
    cluster = get_cluster(maas, desired['cluster_name'])

    # Actions if the cluster does not currently exist
    if not cluster:
        if state == 'query':
            # If this is a query, returne it is not found
            module.exit_json(changed=False, found=False)
        elif state == 'present':
            # Not able to create clusters via the API
            module.fail_json(msg='Named cluster does not exist and clusters cannot be programatically created')
        else:
            # If this should be absent, then we are done and in the desired state
            module.exit_json(changed=False)

        # Done with clusters does not exists actions
        return

    # Actions if the cluster does exist
    if state == 'query':
        # If this is a query, return the cluster
        module.exit_json(changed=False, found=True, cluster=cluster)
    elif state == 'present':
        # If we want this to exists check to see if this is different and
        # needs updated
        if different(cluster, desired):
            res = update_cluster(maas, cluster, desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True, cluster=res['status'])
        else:
            # No differences, to nothing to change
            module.exit_json(changed=False, cluster=cluster)
    else:
        # Not able to delete clusters via the API
        module.fail_json(msg='Named cluster exists and clusters cannot be programmatically deleted')
コード例 #24
0
 def setUp(self):
     self.mock_auth = MagicMock()
     self.api_url = "apiurl"
     url_p = PropertyMock(return_value=self.api_url)
     type(self.mock_auth).api_url = url_p
     self.c = MaasClient(self.mock_auth)
コード例 #25
0
 def setUp(self):
     self.c = MaasClient(AUTH)
     self.tag = 'a-test-tag-' + str(uuid.uuid1())
     res = self.c.tag_new(self.tag)
     self.assertTrue(res)
コード例 #26
0
#!/usr/bin/env python
import argparse
from maasclient.auth import MaasAuth
from maasclient import MaasClient

parser = argparse.ArgumentParser()
parser.add_argument("--api_key")
parser.add_argument("--api_url")
args = parser.parse_args()

auth = MaasAuth(api_url=args.api_url, api_key=args.api_key)
maas_client = MaasClient(auth)
print(maas_client.server_hostname)
コード例 #27
0
 def setUp(self):
     self.c = MaasClient(AUTH)
     self.zone_name = 'testzone-' + str(uuid.uuid1())
     res = self.c.zone_new(self.zone_name,
                           'zone created in unittest')
     self.assertTrue(res)
コード例 #28
0
ファイル: maas.py プロジェクト: pan2za/maas
def main():
    module = AnsibleModule(
        argument_spec = dict(
            maas=dict(default='http://localhost/MAAS/api/1.0/'),
            key=dict(required=True),
            options=dict(required=False, type='list'),
            enable_http_proxy=dict(required=False),
            upstream_dns=dict(required=False),
            default_storage_layout=dict(required=False),
            default_osystem=dict(required=False),
            ports_archive=dict(required=False),
            http_proxy=dict(required=False),
            boot_images_auto_import=dict(required=False),
            enable_third_party_drivers=dict(required=False),
            kernel_opts=dict(required=False),
            main_archive=dict(required=False),
            maas_name=dict(required=False),
            curtin_verbose=dict(required=False),
            dnssec_validation=dict(required=False),
            commissioning_distro_series=dict(required=False),
            windows_kms_host=dict(required=False),
            enable_disk_erasing_on_release=dict(required=False),
            default_distro_series=dict(required=False),
            ntp_server=dict(required=False),
            default_min_hwe_kernel=dict(required=False),
            state=dict(default='present', choices=['present', 'query'])
        ),
        supports_check_mode = False
    )

    maas = module.params['maas']
    key = module.params['key']
    options = module.params['options']
    state = module.params['state']

    if state == 'query':
        desired = {x:None for x in options}
    else:
        # Construct a sparsely populate desired state
        desired = remove_null({
            'enable_http_proxy': module.params['enable_http_proxy'],
            'upstream_dns': module.params['upstream_dns'],
            'default_storage_layout': module.params['default_storage_layout'],
            'default_osystem': module.params['default_osystem'],
            'ports_archive': module.params['ports_archive'],
            'http_proxy': module.params['http_proxy'],
            'boot_images_auto_import': module.params['boot_images_auto_import'],
            'enable_third_party_drivers': module.params['enable_third_party_drivers'],
            'kernel_opts': module.params['kernel_opts'],
            'main_archive': module.params['main_archive'],
            'maas_name': module.params['maas_name'],
            'curtin_verbose': module.params['curtin_verbose'],
            'dnssec_validation': module.params['dnssec_validation'],
            'commissioning_distro_series': module.params['commissioning_distro_series'],
            'windows_kms_host': module.params['windows_kms_host'],
            'enable_disk_erasing_on_release': module.params['enable_disk_erasing_on_release'],
            'default_distro_series': module.params['default_distro_series'],
            'ntp_server': module.params['ntp_server'],
            'default_min_hwe_kernel': module.params['default_min_hwe_kernel'],
        })

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    # Attempt to get the configuration from MAAS
    config = get_config(maas, desired)

    if state == 'query':
        # If this is a query, return the options
        module.exit_json(changed=False, found=True, maas=config)
    elif state == 'present':
        # If we want this to exists check to see if this is different and
        # needs updated
        if different(config, desired):
            res = update_config(maas, config, desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True, maas=res['status'])
        else:
            # No differences, to nothing to change
            module.exit_json(changed=False, maas=config)
コード例 #29
0
ファイル: maas_subnet.py プロジェクト: pan2za/maas
def main():
    module = AnsibleModule(argument_spec=dict(
        maas=dict(default='http://localhost/MAAS/api/1.0/'),
        key=dict(required=True),
        name=dict(required=True),
        space=dict(required=False),
        dns_servers=dict(required=False),
        gateway_ip=dict(required=False),
        cidr=dict(required=False),
        state=dict(default='present', choices=['present', 'absent', 'query'])),
                           supports_check_mode=False)

    maas = module.params['maas']
    key = module.params['key']
    state = module.params['state']

    # Construct a sparsely populate desired state
    desired = remove_null({
        'name': module.params['name'],
        'space': module.params['space'],
        'dns_servers': module.params['dns_servers'],
        'gateway_ip': module.params['gateway_ip'],
        'cidr': module.params['cidr'],
    })

    # Authenticate into MAAS
    auth = MaasAuth(maas, key)
    maas = MaasClient(auth)

    # Attempt to get the subnet from MAAS
    subnet = get_subnet(maas, desired['name'])

    # Actions if the subnet does not currently exist
    if not subnet:
        if state == 'query':
            # If this is a query, returne it is not found
            module.exit_json(changed=False, found=False)
        elif state == 'present':
            # If this should be present, then attempt to create it
            res = create_subnet(maas, desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True, subnet=res['status'])
        else:
            # If this should be absent, then we are done and in the desired state
            module.exit_json(changed=False)

        # Done with subnets does not exists actions
        return

    # Actions if the subnet does exist
    if state == 'query':
        # If this is a query, return the subnet
        module.exit_json(changed=False, found=True, subnet=subnet)
    elif state == 'present':
        # If we want this to exists check to see if this is different and
        # needs updated
        if different(subnet, desired):
            res = update_subnet(maas, subnet, desired)
            if res['error']:
                module.fail_json(msg=res['status'])
            else:
                module.exit_json(changed=True,
                                 subnet=res['status'],
                                 debug=debug)
        else:
            # No differences, to nothing to change
            module.exit_json(changed=False, subnet=subnet)
    else:
        # If we don't want this subnet, then delete it
        res = delete_subnet(maas, subnet['name'])
        if res['error']:
            module.fail_json(msg=res['status'])
        else:
            module.exit_json(changed=True, subnet=subnet)
コード例 #30
0
ファイル: core.py プロジェクト: gitter-badger/cloud-installer
 def authenticate_maas(self):
     auth = MaasAuth()
     auth.get_api_key('root')
     self.maas = MaasClient(auth)
     self.maas_state = MaasState(self.maas)
     log.debug('Authenticated against maas api.')