11293St.nateldemoura@f5.comimport pwd 21293St.nateldemoura@f5.comimport grp 31182St.nateldemoura@f5.comimport json 41182St.nateldemoura@f5.comimport unittest 51182St.nateldemoura@f5.comfrom unit.applications.lang.go import TestApplicationGo 61182St.nateldemoura@f5.comfrom unit.feature.isolation import TestFeatureIsolation 71182St.nateldemoura@f5.com 81182St.nateldemoura@f5.com 91182St.nateldemoura@f5.comclass TestGoIsolation(TestApplicationGo): 101182St.nateldemoura@f5.com prerequisites = {'modules': ['go'], 'features': ['isolation']} 111182St.nateldemoura@f5.com 121182St.nateldemoura@f5.com isolation = TestFeatureIsolation() 131182St.nateldemoura@f5.com 141182St.nateldemoura@f5.com @classmethod 151182St.nateldemoura@f5.com def setUpClass(cls, complete_check=True): 161182St.nateldemoura@f5.com unit = super().setUpClass(complete_check=False) 171182St.nateldemoura@f5.com 181182St.nateldemoura@f5.com TestFeatureIsolation().check(cls.available, unit.testdir) 191182St.nateldemoura@f5.com 201182St.nateldemoura@f5.com return unit if not complete_check else unit.complete() 211182St.nateldemoura@f5.com 221182St.nateldemoura@f5.com def isolation_key(self, key): 231182St.nateldemoura@f5.com return key in self.available['features']['isolation'].keys() 241182St.nateldemoura@f5.com 251182St.nateldemoura@f5.com def conf_isolation(self, isolation): 261182St.nateldemoura@f5.com self.assertIn( 271182St.nateldemoura@f5.com 'success', 281182St.nateldemoura@f5.com self.conf(isolation, 'applications/ns_inspect/isolation'), 291182St.nateldemoura@f5.com 'configure isolation', 301182St.nateldemoura@f5.com ) 311182St.nateldemoura@f5.com 321182St.nateldemoura@f5.com def test_isolation_values(self): 331182St.nateldemoura@f5.com self.load('ns_inspect') 341182St.nateldemoura@f5.com 35*1296St.nateldemoura@f5.com obj = self.getjson()['body'] 361182St.nateldemoura@f5.com 371182St.nateldemoura@f5.com for ns, ns_value in self.available['features']['isolation'].items(): 381182St.nateldemoura@f5.com if ns.upper() in obj['NS']: 391182St.nateldemoura@f5.com self.assertEqual( 401182St.nateldemoura@f5.com obj['NS'][ns.upper()], ns_value, '%s match' % ns 411182St.nateldemoura@f5.com ) 421182St.nateldemoura@f5.com 431182St.nateldemoura@f5.com def test_isolation_user(self): 441182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 451182St.nateldemoura@f5.com print('unprivileged clone is not available') 461182St.nateldemoura@f5.com raise unittest.SkipTest() 471182St.nateldemoura@f5.com 481182St.nateldemoura@f5.com self.load('ns_inspect') 491293St.nateldemoura@f5.com 501293St.nateldemoura@f5.com user_id = pwd.getpwnam('nobody').pw_uid 511293St.nateldemoura@f5.com 521293St.nateldemoura@f5.com try: 531293St.nateldemoura@f5.com group_id = grp.getgrnam('nogroup').gr_gid 541293St.nateldemoura@f5.com except: 551293St.nateldemoura@f5.com group_id = grp.getgrnam('nobody').gr_gid 561293St.nateldemoura@f5.com 57*1296St.nateldemoura@f5.com obj = self.getjson()['body'] 581182St.nateldemoura@f5.com 591182St.nateldemoura@f5.com self.assertTrue(obj['UID'] != 0, 'uid not zero') 601182St.nateldemoura@f5.com self.assertTrue(obj['GID'] != 0, 'gid not zero') 611293St.nateldemoura@f5.com 621293St.nateldemoura@f5.com if self.is_su: 631293St.nateldemoura@f5.com self.assertEqual(obj['UID'], user_id, 'uid match') 641293St.nateldemoura@f5.com self.assertEqual(obj['GID'], group_id, 'gid match') 651293St.nateldemoura@f5.com else: 661293St.nateldemoura@f5.com self.assertEqual(obj['UID'], self.uid, 'uid match') 671293St.nateldemoura@f5.com self.assertEqual(obj['GID'], self.gid, 'gid match') 681182St.nateldemoura@f5.com 691182St.nateldemoura@f5.com self.conf_isolation({"namespaces": {"credential": True}}) 701182St.nateldemoura@f5.com 71*1296St.nateldemoura@f5.com obj = self.getjson()['body'] 721182St.nateldemoura@f5.com 731182St.nateldemoura@f5.com # default uid and gid maps current user to nobody 741293St.nateldemoura@f5.com self.assertEqual(obj['UID'], user_id, 'uid nobody') 751293St.nateldemoura@f5.com self.assertEqual(obj['GID'], group_id, 'gid nobody') 761182St.nateldemoura@f5.com 771182St.nateldemoura@f5.com self.conf_isolation( 781182St.nateldemoura@f5.com { 791182St.nateldemoura@f5.com "namespaces": {"credential": True}, 801182St.nateldemoura@f5.com "uidmap": [ 811293St.nateldemoura@f5.com {"container": user_id, "host": self.uid, "size": 1} 821182St.nateldemoura@f5.com ], 831182St.nateldemoura@f5.com "gidmap": [ 841293St.nateldemoura@f5.com {"container": group_id, "host": self.gid, "size": 1} 851182St.nateldemoura@f5.com ], 861182St.nateldemoura@f5.com } 871182St.nateldemoura@f5.com ) 881182St.nateldemoura@f5.com 89*1296St.nateldemoura@f5.com obj = self.getjson()['body'] 901182St.nateldemoura@f5.com 911293St.nateldemoura@f5.com self.assertEqual(obj['UID'], user_id, 'uid match') 921293St.nateldemoura@f5.com self.assertEqual(obj['GID'], group_id, 'gid match') 931182St.nateldemoura@f5.com 941182St.nateldemoura@f5.com def test_isolation_mnt(self): 951182St.nateldemoura@f5.com if not self.isolation_key('mnt'): 961182St.nateldemoura@f5.com print('mnt namespace is not supported') 971182St.nateldemoura@f5.com raise unittest.SkipTest() 981182St.nateldemoura@f5.com 991182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 1001182St.nateldemoura@f5.com print('unprivileged clone is not available') 1011182St.nateldemoura@f5.com raise unittest.SkipTest() 1021182St.nateldemoura@f5.com 1031182St.nateldemoura@f5.com self.load('ns_inspect') 1041182St.nateldemoura@f5.com self.conf_isolation( 1051182St.nateldemoura@f5.com {"namespaces": {"mount": True, "credential": True}} 1061182St.nateldemoura@f5.com ) 1071182St.nateldemoura@f5.com 108*1296St.nateldemoura@f5.com obj = self.getjson()['body'] 1091182St.nateldemoura@f5.com 1101182St.nateldemoura@f5.com # all but user and mnt 1111182St.nateldemoura@f5.com allns = list(self.available['features']['isolation'].keys()) 1121182St.nateldemoura@f5.com allns.remove('user') 1131182St.nateldemoura@f5.com allns.remove('mnt') 1141182St.nateldemoura@f5.com 1151182St.nateldemoura@f5.com for ns in allns: 1161182St.nateldemoura@f5.com if ns.upper() in obj['NS']: 1171182St.nateldemoura@f5.com self.assertEqual( 1181182St.nateldemoura@f5.com obj['NS'][ns.upper()], 1191182St.nateldemoura@f5.com self.available['features']['isolation'][ns], 1201182St.nateldemoura@f5.com '%s match' % ns, 1211182St.nateldemoura@f5.com ) 1221182St.nateldemoura@f5.com 1231182St.nateldemoura@f5.com self.assertNotEqual( 1241182St.nateldemoura@f5.com obj['NS']['MNT'], self.isolation.getns('mnt'), 'mnt set' 1251182St.nateldemoura@f5.com ) 1261182St.nateldemoura@f5.com self.assertNotEqual( 1271182St.nateldemoura@f5.com obj['NS']['USER'], self.isolation.getns('user'), 'user set' 1281182St.nateldemoura@f5.com ) 1291182St.nateldemoura@f5.com 1301182St.nateldemoura@f5.com def test_isolation_pid(self): 1311182St.nateldemoura@f5.com if not self.isolation_key('pid'): 1321182St.nateldemoura@f5.com print('pid namespace is not supported') 1331182St.nateldemoura@f5.com raise unittest.SkipTest() 1341182St.nateldemoura@f5.com 1351182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 1361182St.nateldemoura@f5.com print('unprivileged clone is not available') 1371182St.nateldemoura@f5.com raise unittest.SkipTest() 1381182St.nateldemoura@f5.com 1391182St.nateldemoura@f5.com self.load('ns_inspect') 1401182St.nateldemoura@f5.com self.conf_isolation({"namespaces": {"pid": True, "credential": True}}) 1411182St.nateldemoura@f5.com 142*1296St.nateldemoura@f5.com obj = self.getjson()['body'] 1431182St.nateldemoura@f5.com 1441182St.nateldemoura@f5.com self.assertEqual(obj['PID'], 1, 'pid of container is 1') 1451182St.nateldemoura@f5.com 1461236St.nateldemoura@f5.com def test_isolation_namespace_false(self): 1471236St.nateldemoura@f5.com self.load('ns_inspect') 1481236St.nateldemoura@f5.com allns = list(self.available['features']['isolation'].keys()) 1491236St.nateldemoura@f5.com 1501236St.nateldemoura@f5.com remove_list = ['unprivileged_userns_clone', 'ipc', 'cgroup'] 1511236St.nateldemoura@f5.com allns = [ns for ns in allns if ns not in remove_list] 1521236St.nateldemoura@f5.com 1531236St.nateldemoura@f5.com namespaces = {} 1541236St.nateldemoura@f5.com for ns in allns: 1551236St.nateldemoura@f5.com if ns == 'user': 1561236St.nateldemoura@f5.com namespaces['credential'] = False 1571236St.nateldemoura@f5.com elif ns == 'mnt': 1581236St.nateldemoura@f5.com namespaces['mount'] = False 1591236St.nateldemoura@f5.com elif ns == 'net': 1601236St.nateldemoura@f5.com namespaces['network'] = False 1611236St.nateldemoura@f5.com elif ns == 'uts': 1621236St.nateldemoura@f5.com namespaces['uname'] = False 1631236St.nateldemoura@f5.com else: 1641236St.nateldemoura@f5.com namespaces[ns] = False 1651236St.nateldemoura@f5.com 1661236St.nateldemoura@f5.com self.conf_isolation({"namespaces": namespaces}) 1671236St.nateldemoura@f5.com 168*1296St.nateldemoura@f5.com obj = self.getjson()['body'] 1691236St.nateldemoura@f5.com 1701236St.nateldemoura@f5.com for ns in allns: 1711236St.nateldemoura@f5.com if ns.upper() in obj['NS']: 1721236St.nateldemoura@f5.com self.assertEqual( 1731236St.nateldemoura@f5.com obj['NS'][ns.upper()], 1741236St.nateldemoura@f5.com self.available['features']['isolation'][ns], 1751236St.nateldemoura@f5.com '%s match' % ns, 1761236St.nateldemoura@f5.com ) 1771236St.nateldemoura@f5.com 1781182St.nateldemoura@f5.com 1791182St.nateldemoura@f5.comif __name__ == '__main__': 1801182St.nateldemoura@f5.com TestGoIsolation.main() 181