def setUp(self): cluster = Cluster.objects.create(name="mws-test-1") Host.objects.create(hostname="mws-test-1.dev.mws3.cam.ac.uk", cluster=cluster) NetworkConfig.objects.create(IPv4='198.51.100.255', IPv6='2001:db8:212:8::8c:255', type='ipvxpub', name="mws-12940.mws3.example") NetworkConfig.objects.create(IPv4='192.0.2.255', type='ipv4priv', name='mws-08246.mws3.private.example') NetworkConfig.objects.create(IPv6='2001:db8:212:8::8c:254', name='mws-client1.example', type='ipv6') self.site = Site.objects.create(name="testSite", start_date=datetime.today(), type=ServerType.objects.get(id=1)) self.service = Service.objects.create( type="production", site=self.site, status="ready", network_configuration=NetworkConfig.get_free_prod_service_config()) self.vm = VirtualMachine.objects.create( name="test_vm", token=uuid.uuid4(), service=self.service, network_configuration=NetworkConfig.get_free_host_config(), cluster=which_cluster()) self.vhost1 = self.service.vhosts.create(name="vhost1") self.vhost2 = self.service.vhosts.create(name="vhost2") self.dom1 = self.vhost1.domain_names.create(name="foo.example", status='external')
def preallocate_new_site(servertype=None): """ Create a new :py:class:`~sitesmanagement.models.Site` object with a unique uuid4 as name. The new Site has two :py:class:`~sitesmanagement.models.Service` instances associated with it, "production" and "test". """ if servertype: site = Site.objects.create(name=uuid.uuid4(), disabled=False, preallocated=True, type=servertype) else: site = Site.objects.create(name=uuid.uuid4(), disabled=False, preallocated=True, type=ServerType.objects.get(id=1)) prod_service_netconf = NetworkConfig.get_free_prod_service_config() test_service_netconf = NetworkConfig.get_free_test_service_config() host_netconf = NetworkConfig.get_free_host_config() if not prod_service_netconf or not test_service_netconf or not host_netconf: raise Exception( 'A MWS server cannot be created at this moment because there are no network addresses available' ) prod_service = Service.objects.create( site=site, type='production', network_configuration=prod_service_netconf) Service.objects.create(site=site, type='test', network_configuration=test_service_netconf) new_site_primary_vm(prod_service, host_netconf) LOGGER.info("Preallocated MWS server created '" + str(site.name) + "' with id " + str(site.id))
def create_site(self): cluster = Cluster.objects.create(name="mws-test-1") Host.objects.create(hostname="mws-test-1.dev.mws3.cam.ac.uk", cluster=cluster) site = Site.objects.create(name="testSite", start_date=datetime.today(), type=ServerType.objects.get(id=1)) site.users.add(User.objects.get(username='******')) service = Service.objects.create(site=site, type='production', status="ready", network_configuration=NetworkConfig.get_free_prod_service_config()) VirtualMachine.objects.create(name="test_vm", token=uuid.uuid4(), cluster=which_cluster(), service=service, network_configuration=NetworkConfig.get_free_host_config()) return site
def test_no_permission_views_tests(self): cluster = Cluster.objects.create(name="mws-test-1") Host.objects.create(hostname="mws-test-1.dev.mws3.cam.ac.uk", cluster=cluster) site = Site.objects.create(name="testSite", start_date=datetime.today(), type=ServerType.objects.get(id=1)) service = Service.objects.create(site=site, type='production', status="ready", network_configuration=NetworkConfig.get_free_prod_service_config()) vm = VirtualMachine.objects.create(name="test_vm", token=uuid.uuid4(), cluster=which_cluster(), service=service, network_configuration=NetworkConfig.get_free_host_config()) vhost = Vhost.objects.create(name="default", service=service) dn = DomainName.objects.create(name="testtestest.mws3test.csx.cam.ac.uk", status="accepted", vhost=vhost) unix_group = UnixGroup.objects.create(name="testUnixGroup", service=service) # TODO test index empty self.assertEqual(self.client.get(site.get_absolute_url()).status_code, 403) self.assertEqual(self.client.get(reverse('editsite', kwargs={'site_id': site.id})).status_code, 403) self.assertEqual(self.client.get(reverse(views.service_settings, kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('billing_management', kwargs={'site_id': site.id})).status_code, 403) self.assertEqual(self.client.get(reverse('deletesite', kwargs={'site_id': site.id})).status_code, 403) self.assertEqual(self.client.get(reverse('disablesite', kwargs={'site_id': site.id})).status_code, 403) self.assertEqual(self.client.get(reverse('enablesite', kwargs={'site_id': site.id})).status_code, 403) self.assertEqual(self.client.get(reverse('listvhost', kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('createvhost', kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('sitesmanagement.views.clone_vm_view', kwargs={'site_id': site.id})).status_code, 403) self.assertEqual(self.client.get(reverse('mwsauth.views.auth_change', kwargs={'site_id': site.id})).status_code, 403) self.assertEqual(self.client.get(reverse(views.delete_vm, kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse(views.power_vm, kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse(views.reset_vm, kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('listunixgroups', kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('listunixgroups', kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('createunixgroup', kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('listvhost', kwargs={'service_id': service.id})).status_code, 403) self.assertEqual(self.client.get(reverse('listdomains', kwargs={'vhost_id': vhost.id})).status_code, 403) self.assertEqual(self.client.get(reverse('deletevhost', kwargs={'vhost_id': vhost.id})).status_code, 403) self.assertEqual(self.client.get(reverse(views.certificates, kwargs={'vhost_id': vhost.id})).status_code, 403) self.assertEqual(self.client.get(reverse(views.add_domain, kwargs={'vhost_id': vhost.id})).status_code, 403) self.assertEqual(self.client.get(reverse('deletedomain', kwargs={'domain_id': dn.id})).status_code, 403) self.assertEqual(self.client.get(reverse(views.set_dn_as_main, kwargs={'domain_id': dn.id})).status_code, 403) self.assertEqual(self.client.get(reverse('updateunixgroup', kwargs={'ug_id': unix_group.id})).status_code, 403) self.assertEqual(self.client.get(reverse('deleteunixgroup', kwargs={'ug_id': unix_group.id})).status_code, 403)
def test_view_show(self): response = self.client.get(reverse('showsite', kwargs={'site_id': 1})) self.assertEqual(response.status_code, 302) # Not logged in, redirected to login self.assertTrue(response.url.endswith( '%s?next=%s' % (reverse('raven_login'), reverse('showsite', kwargs={'site_id': 1})))) do_test_login(self, user="******") response = self.client.get(reverse('showsite', kwargs={'site_id': 1})) self.assertEqual(response.status_code, 404) # The Site does not exist NetworkConfig.objects.create(IPv4='131.111.58.253', IPv6='2001:630:212:8::8c:253', type='ipvxpub', name="mws-66424.mws3.csx.cam.ac.uk") NetworkConfig.objects.create(IPv4='172.28.18.253', type='ipv4priv', name='mws-46250.mws3.csx.private.cam.ac.uk') NetworkConfig.objects.create(IPv6='2001:630:212:8::8c:ff4', name='mws-client1', type='ipv6') site = Site.objects.create(name="testSite", start_date=datetime.today(), type=ServerType.objects.get(id=1)) service = Service.objects.create(network_configuration=NetworkConfig.get_free_prod_service_config(), site=site, type='production', status='requested') Vhost.objects.create(name="default", service=service) response = self.client.get(site.get_absolute_url()) self.assertEqual(response.status_code, 403) # The User is not in the list of auth users site.users.add(User.objects.get(username="******")) response = self.client.get(site.get_absolute_url()) self.assertContains(response, "No billing details are available")
def clone_vm_api_call(site): service = site.test_service host_network_configuration = NetworkConfig.get_free_host_config() parameters = {} parameters["site-id"] = "mwssite-%d" % service.site.id parameters["os"] = getattr(settings, 'OS_VERSION', "jessie") if host_network_configuration: netconf = {} if host_network_configuration.IPv4: netconf["IPv4"] = host_network_configuration.IPv4 if host_network_configuration.IPv6: netconf["IPv6"] = host_network_configuration.IPv6 if host_network_configuration.name: netconf["hostname"] = host_network_configuration.name vm = VirtualMachine.objects.create( service=service, token=uuid.uuid4(), network_configuration=host_network_configuration, cluster=which_cluster()) else: raise AttributeError("No host network configuration") parameters["netconf"] = netconf parameters["callback"] = { "endpoint": "%s%s" % (settings.MAIN_DOMAIN, reverse(post_installation)), "vm_id": vm.id, "secret": str(vm.token), } service.status = 'installing' service.save() vm.name = vm.network_configuration.name vm.save() from apimws.models import AnsibleConfiguration AnsibleConfiguration.objects.update_or_create( service=service, key='os', defaults={'value': getattr(settings, "OS_VERSION", "jessie")}) secrets_prealocation_vm(vm) # PHPLibs for phplib in site.production_service.php_libs.all(): phplib.services.add(site.test_service) return True
def test_group_auth_change(self): do_test_login(self, user="******") amc203_user = User.objects.get(username="******") cluster = Cluster.objects.create(name="mws-test-1") Host.objects.create(hostname="mws-test-1.dev.mws3.cam.ac.uk", cluster=cluster) NetworkConfig.objects.create(IPv4='131.111.58.253', IPv6='2001:630:212:8::8c:253', type='ipvxpub', name="mws-66424.mws3.csx.cam.ac.uk") NetworkConfig.objects.create( IPv4='172.28.18.253', type='ipv4priv', name='mws-46250.mws3.csx.private.cam.ac.uk') NetworkConfig.objects.create(IPv6='2001:630:212:8::8c:ff4', name='mws-client1', type='ipv6') NetworkConfig.objects.create(IPv6='2001:630:212:8::8c:ff3', name='mws-client2', type='ipv6') site_with_auth_groups = Site.objects.create( name="test_site2", start_date=datetime.today(), type=ServerType.objects.get(id=1)) service_a = Service.objects.create( type='production', network_configuration=NetworkConfig.get_free_prod_service_config(), site=site_with_auth_groups, status='ready') VirtualMachine.objects.create( token=uuid.uuid4(), service=service_a, network_configuration=NetworkConfig.get_free_host_config(), cluster=which_cluster()) Vhost.objects.create(name="default", service=service_a) information_systems_group = get_or_create_group_by_groupid(101888) site_with_auth_groups.groups.add(information_systems_group) response = self.client.get( reverse(views.auth_change, kwargs={'site_id': site_with_auth_groups.id})) self.assertContains(response, "101888", status_code=200) # User is in an authorised group self.assertNotContains(response, 'crsid: "amc203"', status_code=200) self.assertEqual(len(site_with_auth_groups.users.all()), 0) self.assertEqual(len(site_with_auth_groups.groups.all()), 1) self.assertEqual(site_with_auth_groups.groups.first(), information_systems_group) with mock.patch("apimws.ansible_impl.subprocess") as mock_subprocess: mock_subprocess.check_output.return_value.returncode = 0 response = self.client.post( reverse(views.auth_change, kwargs={'site_id': site_with_auth_groups.id}), { 'users_crsids': "amc203", 'groupids': "101888" # we authorise amc203 user and 101888 group }) mock_subprocess.check_output.assert_called_with( [ "userv", "mws-admin", "mws_ansible_host", site_with_auth_groups.production_service.virtual_machines. first().network_configuration.name ], stderr=mock_subprocess.STDOUT) self.assertRedirects( response, expected_url=site_with_auth_groups.get_absolute_url()) self.assertEqual(len(site_with_auth_groups.users.all()), 1) self.assertEqual(site_with_auth_groups.users.first(), amc203_user) self.assertEqual(len(site_with_auth_groups.groups.all()), 1) self.assertEqual(site_with_auth_groups.groups.first(), information_systems_group) with mock.patch("apimws.ansible_impl.subprocess") as mock_subprocess: mock_subprocess.check_output.return_value.returncode = 0 # remove all users and groups authorised, we do not send any crsids or groupids response = self.client.post( reverse(views.auth_change, kwargs={'site_id': site_with_auth_groups.id}), {}) mock_subprocess.check_output.assert_called_with( [ "userv", "mws-admin", "mws_ansible_host", site_with_auth_groups.production_service.virtual_machines. first().network_configuration.name ], stderr=mock_subprocess.STDOUT) self.assertEqual(response.status_code, 302) self.assertTrue( response.url.endswith(site_with_auth_groups.get_absolute_url())) self.assertEqual(self.client.get(response.url).status_code, 403) # User is no longer authorised self.assertEqual(len(site_with_auth_groups.users.all()), 0) self.assertEqual(len(site_with_auth_groups.groups.all()), 0)
def test_view_billing(self): response = self.client.get( reverse('billing_management', kwargs={'site_id': 1})) self.assertEqual(response.status_code, 302) # Not logged in, redirected to login self.assertTrue( response.url.endswith( '%s?next=%s' % (reverse('raven_login'), reverse('billing_management', kwargs={'site_id': 1})))) do_test_login(self, user="******") response = self.client.get( reverse('billing_management', kwargs={'site_id': 1})) self.assertEqual(response.status_code, 404) # The Site does not exist cluster = Cluster.objects.create(name="mws-test-1") Host.objects.create(hostname="mws-test-1.dev.mws3.cam.ac.uk", cluster=cluster) NetworkConfig.objects.create(IPv4='131.111.58.253', IPv6='2001:630:212:8::8c:253', type='ipvxpub', name="mws-66424.mws3.csx.cam.ac.uk") NetworkConfig.objects.create( IPv4='172.28.18.253', type='ipv4priv', name='mws-46250.mws3.csx.private.cam.ac.uk') NetworkConfig.objects.create(IPv6='2001:630:212:8::8c:ff4', name='mws-client1', type='ipv6') NetworkConfig.objects.create(IPv6='2001:630:212:8::8c:ff3', name='mws-client2', type='ipv6') NetworkConfig.objects.create(IPv6='2001:630:212:8::8c:ff2', name='mws-client3', type='ipv6') NetworkConfig.objects.create(IPv6='2001:630:212:8::8c:ff1', name='mws-client4', type='ipv6') site = Site.objects.create(name="testSite", start_date=datetime.today(), type=ServerType.objects.get(id=1)) service = Service.objects.create( site=site, type='production', status="ready", network_configuration=NetworkConfig.get_free_prod_service_config()) VirtualMachine.objects.create( name="test_vm", token=uuid.uuid4(), cluster=which_cluster(), service=service, network_configuration=NetworkConfig.get_free_host_config()) Vhost.objects.create(name="default", service=service) response = self.client.get( reverse('billing_management', kwargs={'site_id': site.id})) self.assertEqual(response.status_code, 403) # The User is not in the list of auth users site.users.add(User.objects.get(username="******")) response = self.client.get( reverse('billing_management', kwargs={'site_id': site.id})) self.assertContains(response, "Billing data") response = self.client.get(site.get_absolute_url()) self.assertContains(response, "No billing details are available") with mock.patch("apimws.vm.change_vm_power_state" ) as mock_change_vm_power_state: mock_change_vm_power_state.return_value = True mock_change_vm_power_state.delay.return_value = True site.disable() suspension = site.suspend_now(input_reason="test suspension") response = self.client.get( reverse('billing_management', kwargs={'site_id': site.id})) self.assertEqual(response.status_code, 403) # The site is suspended with mock.patch("apimws.vm.change_vm_power_state" ) as mock_change_vm_power_state: mock_change_vm_power_state.return_value = True mock_change_vm_power_state.delay.return_value = True with mock.patch("apimws.ansible.subprocess") as mock_subprocess: mock_subprocess.check_output.return_value.returncode = 0 site.enable() suspension.start_date = datetime.today() - timedelta(days=2) suspension.end_date = datetime.today() - timedelta(days=1) suspension.save() response = self.client.get( reverse('billing_management', kwargs={'site_id': site.id})) self.assertContains(response, "Billing data") self.assertFalse(hasattr(site, 'billing')) pofile = SimpleUploadedFile("file.pdf", "file_content") response = self.client.post( reverse('billing_management', kwargs={'site_id': site.id}), { 'purchase_order_number': 'testOrderNumber', 'group': 'testGroup', 'purchase_order': pofile }) self.assertRedirects( response, expected_url=site.get_absolute_url()) # Changes done, redirecting site_changed = Site.objects.get(pk=site.id) self.assertEqual(site_changed.billing.purchase_order_number, 'testOrderNumber') self.assertEqual(site_changed.billing.group, 'testGroup') self.assertRegexpMatches(site_changed.billing.purchase_order.name, 'billing/file.*\.pdf') self.assertRegexpMatches(site_changed.billing.purchase_order.url, '/media/billing/file.*\.pdf') response = self.client.get(response.url) self.assertNotContains(response, "No Billing, please add one.") site_changed.billing.purchase_order.delete() site = Site.objects.get(pk=site.id) response = self.client.get( reverse('billing_management', kwargs={'site_id': site.id})) self.assertContains(response, "testOrderNumber") self.assertContains(response, "testGroup") self.assertTrue(hasattr(site, 'billing')) pofile = SimpleUploadedFile("file.pdf", "file_content") response = self.client.post( reverse('billing_management', kwargs={'site_id': site.id}), { 'purchase_order_number': 'testOrderNumber1', 'group': 'testGroup1', 'purchase_order': pofile }) self.assertRedirects( response, expected_url=site.get_absolute_url()) # Changes done, redirecting site_changed = Site.objects.get(pk=site.id) self.assertEqual(site_changed.billing.purchase_order_number, 'testOrderNumber1') self.assertEqual(site_changed.billing.group, 'testGroup1') self.assertRegexpMatches(site_changed.billing.purchase_order.name, 'billing/file.*\.pdf') self.assertRegexpMatches(site_changed.billing.purchase_order.url, '/media/billing/file.*\.pdf') response = self.client.get(response.url) self.assertNotContains(response, "No Billing, please add one.") site_changed.billing.purchase_order.delete()
def test_vm_is_busy(self): site = self.create_site() service = site.production_service service.status = "requested" service.save() service2 = Service.objects.create( site=site, type='test', status="requested", network_configuration=NetworkConfig.get_free_prod_service_config()) VirtualMachine.objects.create( name="test_vm2", token=uuid.uuid4(), service=service2, cluster=which_cluster(), network_configuration=NetworkConfig.get_free_host_config()) vhost = Vhost.objects.create(name="default", service=service) dn = DomainName.objects.create( name="testtestest.mws3test.csx.cam.ac.uk", status="accepted", vhost=vhost) unix_group = UnixGroup.objects.create(name="testUnixGroup", service=service) # TODO test index not empty self.assertRedirects(self.client.get( reverse('editsite', kwargs={'site_id': site.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse(views.service_settings, kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertEqual( self.client.get( reverse('billing_management', kwargs={'site_id': site.id})).status_code, 200) # self.assertRedirects(self.client.get(reverse('deletesite', kwargs={'site_id': site.id})), # expected_url=site.get_absolute_url()) # self.assertRedirects(self.client.get(reverse('disablesite', kwargs={'site_id': site.id})), # expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('enablesite', kwargs={'site_id': site.id})), expected_url=reverse('listsites')) self.assertRedirects(self.client.get( reverse('listvhost', kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('createvhost', kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('mwsauth.views.auth_change', kwargs={'site_id': site.id})), expected_url=site.get_absolute_url()) self.assertEqual( self.client.get( reverse(views.delete_vm, kwargs={'service_id': service.id})).status_code, 403) # Primary VM cannot be deleted self.assertRedirects(self.client.get( reverse(views.delete_vm, kwargs={'service_id': service2.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse(views.power_vm, kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse(views.reset_vm, kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('listunixgroups', kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('createunixgroup', kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('listvhost', kwargs={'service_id': service.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('listdomains', kwargs={'vhost_id': vhost.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('deletevhost', kwargs={'vhost_id': vhost.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse(views.certificates, kwargs={'vhost_id': vhost.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse(views.add_domain, kwargs={'vhost_id': vhost.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('deletedomain', kwargs={'domain_id': dn.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse(views.set_dn_as_main, kwargs={'domain_id': dn.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('updateunixgroup', kwargs={'ug_id': unix_group.id})), expected_url=site.get_absolute_url()) self.assertRedirects(self.client.get( reverse('deleteunixgroup', kwargs={'ug_id': unix_group.id})), expected_url=site.get_absolute_url())
def clone_vm_api_call(site): service = site.test_service host_network_configuration = NetworkConfig.get_free_host_config() parameters = {} parameters["site-id"] = "mwssite-%d" % service.site.id parameters["os"] = getattr(settings, 'OS_VERSION', "stretch") if host_network_configuration: netconf = {} if host_network_configuration.IPv4: netconf["IPv4"] = host_network_configuration.IPv4 if host_network_configuration.IPv6: netconf["IPv6"] = host_network_configuration.IPv6 if host_network_configuration.name: netconf["hostname"] = host_network_configuration.name vm = VirtualMachine.objects.create( service=service, token=uuid.uuid4(), network_configuration=host_network_configuration, cluster=which_cluster()) else: raise AttributeError("No host network configuration") parameters["netconf"] = netconf parameters["callback"] = { "endpoint": "%s%s" % (settings.MAIN_DOMAIN, reverse(post_installation)), "vm_id": vm.id, "secret": str(vm.token), } parameters["features"] = { "cpu": service.site.type.numcpu, "ram": service.site.type.sizeram * 1024, "disk": service.site.type.sizedisk, } service.status = 'installing' service.save() response = vm_api_request(command='create', parameters=parameters, vm=vm) try: jresponse = json.loads(response) except ValueError as e: LOGGER.error("VM API response is not properly formated: %s", response) vm.name = vm.network_configuration.name vm.save() raise e try: if 'vmid' in jresponse: vm.name = jresponse['vmid'] else: vm.name = vm.network_configuration.name except Exception as e: vm.name = vm.network_configuration.name vm.save() from apimws.models import AnsibleConfiguration AnsibleConfiguration.objects.update_or_create( service=service, key='os', defaults={'value': getattr(settings, "OS_VERSION", "stretch")}) secrets_prealocation_vm(vm) # PHPLibs for phplib in site.production_service.php_libs.all(): phplib.services.add(site.test_service) # Call Ansible to update the state of the machine launch_ansible(site.production_service) launch_ansible(site.test_service) return True