11182St.nateldemoura@f5.comimport os 21182St.nateldemoura@f5.comimport json 31182St.nateldemoura@f5.comimport unittest 41182St.nateldemoura@f5.comfrom unit.applications.lang.go import TestApplicationGo 51182St.nateldemoura@f5.comfrom unit.feature.isolation import TestFeatureIsolation 61182St.nateldemoura@f5.com 71182St.nateldemoura@f5.com 81182St.nateldemoura@f5.comclass TestGoIsolation(TestApplicationGo): 91182St.nateldemoura@f5.com prerequisites = {'modules': ['go'], 'features': ['isolation']} 101182St.nateldemoura@f5.com 111182St.nateldemoura@f5.com isolation = TestFeatureIsolation() 121182St.nateldemoura@f5.com 131182St.nateldemoura@f5.com @classmethod 141182St.nateldemoura@f5.com def setUpClass(cls, complete_check=True): 151182St.nateldemoura@f5.com unit = super().setUpClass(complete_check=False) 161182St.nateldemoura@f5.com 171182St.nateldemoura@f5.com TestFeatureIsolation().check(cls.available, unit.testdir) 181182St.nateldemoura@f5.com 191182St.nateldemoura@f5.com return unit if not complete_check else unit.complete() 201182St.nateldemoura@f5.com 211182St.nateldemoura@f5.com def isolation_key(self, key): 221182St.nateldemoura@f5.com return key in self.available['features']['isolation'].keys() 231182St.nateldemoura@f5.com 241182St.nateldemoura@f5.com def conf_isolation(self, isolation): 251182St.nateldemoura@f5.com self.assertIn( 261182St.nateldemoura@f5.com 'success', 271182St.nateldemoura@f5.com self.conf(isolation, 'applications/ns_inspect/isolation'), 281182St.nateldemoura@f5.com 'configure isolation', 291182St.nateldemoura@f5.com ) 301182St.nateldemoura@f5.com 311182St.nateldemoura@f5.com def test_isolation_values(self): 321182St.nateldemoura@f5.com self.load('ns_inspect') 331182St.nateldemoura@f5.com 341182St.nateldemoura@f5.com obj = self.isolation.parsejson(self.get()['body']) 351182St.nateldemoura@f5.com 361182St.nateldemoura@f5.com for ns, ns_value in self.available['features']['isolation'].items(): 371182St.nateldemoura@f5.com if ns.upper() in obj['NS']: 381182St.nateldemoura@f5.com self.assertEqual( 391182St.nateldemoura@f5.com obj['NS'][ns.upper()], ns_value, '%s match' % ns 401182St.nateldemoura@f5.com ) 411182St.nateldemoura@f5.com 421182St.nateldemoura@f5.com def test_isolation_user(self): 431182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 441182St.nateldemoura@f5.com print('unprivileged clone is not available') 451182St.nateldemoura@f5.com raise unittest.SkipTest() 461182St.nateldemoura@f5.com 471182St.nateldemoura@f5.com self.load('ns_inspect') 481182St.nateldemoura@f5.com obj = self.isolation.parsejson(self.get()['body']) 491182St.nateldemoura@f5.com 501182St.nateldemoura@f5.com self.assertTrue(obj['UID'] != 0, 'uid not zero') 511182St.nateldemoura@f5.com self.assertTrue(obj['GID'] != 0, 'gid not zero') 521182St.nateldemoura@f5.com self.assertEqual(obj['UID'], os.getuid(), 'uid match') 531182St.nateldemoura@f5.com self.assertEqual(obj['GID'], os.getgid(), 'gid match') 541182St.nateldemoura@f5.com 551182St.nateldemoura@f5.com self.conf_isolation({"namespaces": {"credential": True}}) 561182St.nateldemoura@f5.com 571182St.nateldemoura@f5.com obj = self.isolation.parsejson(self.get()['body']) 581182St.nateldemoura@f5.com 591182St.nateldemoura@f5.com # default uid and gid maps current user to nobody 601182St.nateldemoura@f5.com self.assertEqual(obj['UID'], 65534, 'uid nobody') 611182St.nateldemoura@f5.com self.assertEqual(obj['GID'], 65534, 'gid nobody') 621182St.nateldemoura@f5.com 631182St.nateldemoura@f5.com self.conf_isolation( 641182St.nateldemoura@f5.com { 651182St.nateldemoura@f5.com "namespaces": {"credential": True}, 661182St.nateldemoura@f5.com "uidmap": [ 671182St.nateldemoura@f5.com {"container": 1000, "host": os.geteuid(), "size": 1} 681182St.nateldemoura@f5.com ], 691182St.nateldemoura@f5.com "gidmap": [ 701182St.nateldemoura@f5.com {"container": 1000, "host": os.getegid(), "size": 1} 711182St.nateldemoura@f5.com ], 721182St.nateldemoura@f5.com } 731182St.nateldemoura@f5.com ) 741182St.nateldemoura@f5.com 751182St.nateldemoura@f5.com obj = self.isolation.parsejson(self.get()['body']) 761182St.nateldemoura@f5.com 771182St.nateldemoura@f5.com # default uid and gid maps current user to root 781182St.nateldemoura@f5.com self.assertEqual(obj['UID'], 1000, 'uid root') 791182St.nateldemoura@f5.com self.assertEqual(obj['GID'], 1000, 'gid root') 801182St.nateldemoura@f5.com 811182St.nateldemoura@f5.com def test_isolation_mnt(self): 821182St.nateldemoura@f5.com if not self.isolation_key('mnt'): 831182St.nateldemoura@f5.com print('mnt namespace is not supported') 841182St.nateldemoura@f5.com raise unittest.SkipTest() 851182St.nateldemoura@f5.com 861182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 871182St.nateldemoura@f5.com print('unprivileged clone is not available') 881182St.nateldemoura@f5.com raise unittest.SkipTest() 891182St.nateldemoura@f5.com 901182St.nateldemoura@f5.com self.load('ns_inspect') 911182St.nateldemoura@f5.com self.conf_isolation( 921182St.nateldemoura@f5.com {"namespaces": {"mount": True, "credential": True}} 931182St.nateldemoura@f5.com ) 941182St.nateldemoura@f5.com 951182St.nateldemoura@f5.com obj = self.isolation.parsejson(self.get()['body']) 961182St.nateldemoura@f5.com 971182St.nateldemoura@f5.com # all but user and mnt 981182St.nateldemoura@f5.com allns = list(self.available['features']['isolation'].keys()) 991182St.nateldemoura@f5.com allns.remove('user') 1001182St.nateldemoura@f5.com allns.remove('mnt') 1011182St.nateldemoura@f5.com 1021182St.nateldemoura@f5.com for ns in allns: 1031182St.nateldemoura@f5.com if ns.upper() in obj['NS']: 1041182St.nateldemoura@f5.com self.assertEqual( 1051182St.nateldemoura@f5.com obj['NS'][ns.upper()], 1061182St.nateldemoura@f5.com self.available['features']['isolation'][ns], 1071182St.nateldemoura@f5.com '%s match' % ns, 1081182St.nateldemoura@f5.com ) 1091182St.nateldemoura@f5.com 1101182St.nateldemoura@f5.com self.assertNotEqual( 1111182St.nateldemoura@f5.com obj['NS']['MNT'], self.isolation.getns('mnt'), 'mnt set' 1121182St.nateldemoura@f5.com ) 1131182St.nateldemoura@f5.com self.assertNotEqual( 1141182St.nateldemoura@f5.com obj['NS']['USER'], self.isolation.getns('user'), 'user set' 1151182St.nateldemoura@f5.com ) 1161182St.nateldemoura@f5.com 1171182St.nateldemoura@f5.com def test_isolation_pid(self): 1181182St.nateldemoura@f5.com if not self.isolation_key('pid'): 1191182St.nateldemoura@f5.com print('pid namespace is not supported') 1201182St.nateldemoura@f5.com raise unittest.SkipTest() 1211182St.nateldemoura@f5.com 1221182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 1231182St.nateldemoura@f5.com print('unprivileged clone is not available') 1241182St.nateldemoura@f5.com raise unittest.SkipTest() 1251182St.nateldemoura@f5.com 1261182St.nateldemoura@f5.com self.load('ns_inspect') 1271182St.nateldemoura@f5.com self.conf_isolation({"namespaces": {"pid": True, "credential": True}}) 1281182St.nateldemoura@f5.com 1291182St.nateldemoura@f5.com obj = self.isolation.parsejson(self.get()['body']) 1301182St.nateldemoura@f5.com 1311182St.nateldemoura@f5.com self.assertEqual(obj['PID'], 1, 'pid of container is 1') 1321182St.nateldemoura@f5.com 133*1236St.nateldemoura@f5.com def test_isolation_namespace_false(self): 134*1236St.nateldemoura@f5.com self.load('ns_inspect') 135*1236St.nateldemoura@f5.com allns = list(self.available['features']['isolation'].keys()) 136*1236St.nateldemoura@f5.com 137*1236St.nateldemoura@f5.com remove_list = ['unprivileged_userns_clone', 'ipc', 'cgroup'] 138*1236St.nateldemoura@f5.com allns = [ns for ns in allns if ns not in remove_list] 139*1236St.nateldemoura@f5.com 140*1236St.nateldemoura@f5.com namespaces = {} 141*1236St.nateldemoura@f5.com for ns in allns: 142*1236St.nateldemoura@f5.com if ns == 'user': 143*1236St.nateldemoura@f5.com namespaces['credential'] = False 144*1236St.nateldemoura@f5.com elif ns == 'mnt': 145*1236St.nateldemoura@f5.com namespaces['mount'] = False 146*1236St.nateldemoura@f5.com elif ns == 'net': 147*1236St.nateldemoura@f5.com namespaces['network'] = False 148*1236St.nateldemoura@f5.com elif ns == 'uts': 149*1236St.nateldemoura@f5.com namespaces['uname'] = False 150*1236St.nateldemoura@f5.com else: 151*1236St.nateldemoura@f5.com namespaces[ns] = False 152*1236St.nateldemoura@f5.com 153*1236St.nateldemoura@f5.com self.conf_isolation({"namespaces": namespaces}) 154*1236St.nateldemoura@f5.com 155*1236St.nateldemoura@f5.com obj = self.isolation.parsejson(self.get()['body']) 156*1236St.nateldemoura@f5.com 157*1236St.nateldemoura@f5.com for ns in allns: 158*1236St.nateldemoura@f5.com if ns.upper() in obj['NS']: 159*1236St.nateldemoura@f5.com self.assertEqual( 160*1236St.nateldemoura@f5.com obj['NS'][ns.upper()], 161*1236St.nateldemoura@f5.com self.available['features']['isolation'][ns], 162*1236St.nateldemoura@f5.com '%s match' % ns, 163*1236St.nateldemoura@f5.com ) 164*1236St.nateldemoura@f5.com 1651182St.nateldemoura@f5.com 1661182St.nateldemoura@f5.comif __name__ == '__main__': 1671182St.nateldemoura@f5.com TestGoIsolation.main() 168