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 22*1307St.nateldemoura@f5.com def unpriv_creds(self): 23*1307St.nateldemoura@f5.com nobody_uid = pwd.getpwnam('nobody').pw_uid 24*1307St.nateldemoura@f5.com 25*1307St.nateldemoura@f5.com try: 26*1307St.nateldemoura@f5.com nogroup_gid = grp.getgrnam('nogroup').gr_gid 27*1307St.nateldemoura@f5.com nogroup = 'nogroup' 28*1307St.nateldemoura@f5.com except: 29*1307St.nateldemoura@f5.com nogroup_gid = grp.getgrnam('nobody').gr_gid 30*1307St.nateldemoura@f5.com nogroup = 'nobody' 31*1307St.nateldemoura@f5.com 32*1307St.nateldemoura@f5.com return (nobody_uid, nogroup_gid, nogroup) 33*1307St.nateldemoura@f5.com 341182St.nateldemoura@f5.com def isolation_key(self, key): 351182St.nateldemoura@f5.com return key in self.available['features']['isolation'].keys() 361182St.nateldemoura@f5.com 371182St.nateldemoura@f5.com def test_isolation_values(self): 381182St.nateldemoura@f5.com self.load('ns_inspect') 391182St.nateldemoura@f5.com 401296St.nateldemoura@f5.com obj = self.getjson()['body'] 411182St.nateldemoura@f5.com 421182St.nateldemoura@f5.com for ns, ns_value in self.available['features']['isolation'].items(): 431182St.nateldemoura@f5.com if ns.upper() in obj['NS']: 441182St.nateldemoura@f5.com self.assertEqual( 451182St.nateldemoura@f5.com obj['NS'][ns.upper()], ns_value, '%s match' % ns 461182St.nateldemoura@f5.com ) 471182St.nateldemoura@f5.com 48*1307St.nateldemoura@f5.com def test_isolation_unpriv_user(self): 491182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 501182St.nateldemoura@f5.com print('unprivileged clone is not available') 511182St.nateldemoura@f5.com raise unittest.SkipTest() 521182St.nateldemoura@f5.com 53*1307St.nateldemoura@f5.com if self.is_su: 54*1307St.nateldemoura@f5.com print('privileged tests, skip this') 55*1307St.nateldemoura@f5.com raise unittest.SkipTest() 56*1307St.nateldemoura@f5.com 57*1307St.nateldemoura@f5.com self.load('ns_inspect') 58*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 59*1307St.nateldemoura@f5.com 60*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], self.uid, 'uid match') 61*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], self.gid, 'gid match') 62*1307St.nateldemoura@f5.com 63*1307St.nateldemoura@f5.com self.load('ns_inspect', isolation={'namespaces': {'credential': True}}) 64*1307St.nateldemoura@f5.com 65*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 66*1307St.nateldemoura@f5.com 67*1307St.nateldemoura@f5.com nobody_uid, nogroup_gid, nogroup = self.unpriv_creds() 68*1307St.nateldemoura@f5.com 69*1307St.nateldemoura@f5.com # unprivileged unit map itself to nobody in the container by default 70*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], nobody_uid, 'uid of nobody') 71*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], nogroup_gid, 'gid of %s' % nogroup) 72*1307St.nateldemoura@f5.com 73*1307St.nateldemoura@f5.com self.load( 74*1307St.nateldemoura@f5.com 'ns_inspect', 75*1307St.nateldemoura@f5.com user='root', 76*1307St.nateldemoura@f5.com isolation={'namespaces': {'credential': True}}, 77*1307St.nateldemoura@f5.com ) 78*1307St.nateldemoura@f5.com 79*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 80*1307St.nateldemoura@f5.com 81*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], 0, 'uid match user=root') 82*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], 0, 'gid match user=root') 83*1307St.nateldemoura@f5.com 84*1307St.nateldemoura@f5.com self.load( 85*1307St.nateldemoura@f5.com 'ns_inspect', 86*1307St.nateldemoura@f5.com user='root', 87*1307St.nateldemoura@f5.com group=nogroup, 88*1307St.nateldemoura@f5.com isolation={'namespaces': {'credential': True}}, 89*1307St.nateldemoura@f5.com ) 90*1307St.nateldemoura@f5.com 91*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 92*1307St.nateldemoura@f5.com 93*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], 0, 'uid match user=root group=nogroup') 94*1307St.nateldemoura@f5.com self.assertEqual( 95*1307St.nateldemoura@f5.com obj['GID'], nogroup_gid, 'gid match user=root group=nogroup' 96*1307St.nateldemoura@f5.com ) 97*1307St.nateldemoura@f5.com 98*1307St.nateldemoura@f5.com self.load( 99*1307St.nateldemoura@f5.com 'ns_inspect', 100*1307St.nateldemoura@f5.com user='root', 101*1307St.nateldemoura@f5.com group='root', 102*1307St.nateldemoura@f5.com isolation={ 103*1307St.nateldemoura@f5.com 'namespaces': {'credential': True}, 104*1307St.nateldemoura@f5.com 'uidmap': [{'container': 0, 'host': self.uid, 'size': 1}], 105*1307St.nateldemoura@f5.com 'gidmap': [{'container': 0, 'host': self.gid, 'size': 1}], 106*1307St.nateldemoura@f5.com }, 107*1307St.nateldemoura@f5.com ) 108*1307St.nateldemoura@f5.com 109*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 110*1307St.nateldemoura@f5.com 111*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], 0, 'uid match uidmap') 112*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], 0, 'gid match gidmap') 113*1307St.nateldemoura@f5.com 114*1307St.nateldemoura@f5.com def test_isolation_priv_user(self): 115*1307St.nateldemoura@f5.com if not self.is_su: 116*1307St.nateldemoura@f5.com print('unprivileged tests, skip this') 117*1307St.nateldemoura@f5.com raise unittest.SkipTest() 118*1307St.nateldemoura@f5.com 1191182St.nateldemoura@f5.com self.load('ns_inspect') 1201293St.nateldemoura@f5.com 121*1307St.nateldemoura@f5.com nobody_uid, nogroup_gid, nogroup = self.unpriv_creds() 122*1307St.nateldemoura@f5.com 123*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 1241293St.nateldemoura@f5.com 125*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], nobody_uid, 'uid match') 126*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], nogroup_gid, 'gid match') 127*1307St.nateldemoura@f5.com 128*1307St.nateldemoura@f5.com self.load('ns_inspect', isolation={'namespaces': {'credential': True}}) 1291293St.nateldemoura@f5.com 1301296St.nateldemoura@f5.com obj = self.getjson()['body'] 1311182St.nateldemoura@f5.com 132*1307St.nateldemoura@f5.com # privileged unit map app creds in the container by default 133*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], nobody_uid, 'uid nobody') 134*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], nogroup_gid, 'gid nobody') 1351293St.nateldemoura@f5.com 136*1307St.nateldemoura@f5.com self.load( 137*1307St.nateldemoura@f5.com 'ns_inspect', 138*1307St.nateldemoura@f5.com user='root', 139*1307St.nateldemoura@f5.com isolation={'namespaces': {'credential': True}}, 140*1307St.nateldemoura@f5.com ) 1411182St.nateldemoura@f5.com 1421296St.nateldemoura@f5.com obj = self.getjson()['body'] 1431182St.nateldemoura@f5.com 144*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], 0, 'uid nobody user=root') 145*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], 0, 'gid nobody user=root') 1461182St.nateldemoura@f5.com 147*1307St.nateldemoura@f5.com self.load( 148*1307St.nateldemoura@f5.com 'ns_inspect', 149*1307St.nateldemoura@f5.com user='root', 150*1307St.nateldemoura@f5.com group=nogroup, 151*1307St.nateldemoura@f5.com isolation={'namespaces': {'credential': True}}, 1521182St.nateldemoura@f5.com ) 1531182St.nateldemoura@f5.com 1541296St.nateldemoura@f5.com obj = self.getjson()['body'] 1551182St.nateldemoura@f5.com 156*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], 0, 'uid match user=root group=nogroup') 157*1307St.nateldemoura@f5.com self.assertEqual( 158*1307St.nateldemoura@f5.com obj['GID'], nogroup_gid, 'gid match user=root group=nogroup' 159*1307St.nateldemoura@f5.com ) 160*1307St.nateldemoura@f5.com 161*1307St.nateldemoura@f5.com self.load( 162*1307St.nateldemoura@f5.com 'ns_inspect', 163*1307St.nateldemoura@f5.com user='root', 164*1307St.nateldemoura@f5.com group='root', 165*1307St.nateldemoura@f5.com isolation={ 166*1307St.nateldemoura@f5.com 'namespaces': {'credential': True}, 167*1307St.nateldemoura@f5.com 'uidmap': [{'container': 0, 'host': 0, 'size': 1}], 168*1307St.nateldemoura@f5.com 'gidmap': [{'container': 0, 'host': 0, 'size': 1}], 169*1307St.nateldemoura@f5.com }, 170*1307St.nateldemoura@f5.com ) 171*1307St.nateldemoura@f5.com 172*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 173*1307St.nateldemoura@f5.com 174*1307St.nateldemoura@f5.com self.assertEqual(obj['UID'], 0, 'uid match uidmap user=root') 175*1307St.nateldemoura@f5.com self.assertEqual(obj['GID'], 0, 'gid match gidmap user=root') 176*1307St.nateldemoura@f5.com 177*1307St.nateldemoura@f5.com # map 65535 uids 178*1307St.nateldemoura@f5.com self.load( 179*1307St.nateldemoura@f5.com 'ns_inspect', 180*1307St.nateldemoura@f5.com user='nobody', 181*1307St.nateldemoura@f5.com isolation={ 182*1307St.nateldemoura@f5.com 'namespaces': {'credential': True}, 183*1307St.nateldemoura@f5.com 'uidmap': [ 184*1307St.nateldemoura@f5.com {'container': 0, 'host': 0, 'size': nobody_uid + 1} 185*1307St.nateldemoura@f5.com ], 186*1307St.nateldemoura@f5.com }, 187*1307St.nateldemoura@f5.com ) 188*1307St.nateldemoura@f5.com 189*1307St.nateldemoura@f5.com obj = self.getjson()['body'] 190*1307St.nateldemoura@f5.com 191*1307St.nateldemoura@f5.com self.assertEqual( 192*1307St.nateldemoura@f5.com obj['UID'], nobody_uid, 'uid match uidmap user=nobody' 193*1307St.nateldemoura@f5.com ) 194*1307St.nateldemoura@f5.com self.assertEqual( 195*1307St.nateldemoura@f5.com obj['GID'], nogroup_gid, 'gid match uidmap user=nobody' 196*1307St.nateldemoura@f5.com ) 1971182St.nateldemoura@f5.com 1981182St.nateldemoura@f5.com def test_isolation_mnt(self): 1991182St.nateldemoura@f5.com if not self.isolation_key('mnt'): 2001182St.nateldemoura@f5.com print('mnt namespace is not supported') 2011182St.nateldemoura@f5.com raise unittest.SkipTest() 2021182St.nateldemoura@f5.com 2031182St.nateldemoura@f5.com if not self.isolation_key('unprivileged_userns_clone'): 2041182St.nateldemoura@f5.com print('unprivileged clone is not available') 2051182St.nateldemoura@f5.com raise unittest.SkipTest() 2061182St.nateldemoura@f5.com 207*1307St.nateldemoura@f5.com self.load( 208*1307St.nateldemoura@f5.com 'ns_inspect', 209*1307St.nateldemoura@f5.com isolation={'namespaces': {'mount': True, 'credential': True}}, 2101182St.nateldemoura@f5.com ) 2111182St.nateldemoura@f5.com 2121296St.nateldemoura@f5.com obj = self.getjson()['body'] 2131182St.nateldemoura@f5.com 2141182St.nateldemoura@f5.com # all but user and mnt 2151182St.nateldemoura@f5.com allns = list(self.available['features']['isolation'].keys()) 2161182St.nateldemoura@f5.com allns.remove('user') 2171182St.nateldemoura@f5.com allns.remove('mnt') 2181182St.nateldemoura@f5.com 2191182St.nateldemoura@f5.com for ns in allns: 2201182St.nateldemoura@f5.com if ns.upper() in obj['NS']: 2211182St.nateldemoura@f5.com self.assertEqual( 2221182St.nateldemoura@f5.com obj['NS'][ns.upper()], 2231182St.nateldemoura@f5.com self.available['features']['isolation'][ns], 2241182St.nateldemoura@f5.com '%s match' % ns, 2251182St.nateldemoura@f5.com ) 2261182St.nateldemoura@f5.com 2271182St.nateldemoura@f5.com self.assertNotEqual( 2281182St.nateldemoura@f5.com obj['NS']['MNT'], self.isolation.getns('mnt'), 'mnt set' 2291182St.nateldemoura@f5.com ) 2301182St.nateldemoura@f5.com self.assertNotEqual( 2311182St.nateldemoura@f5.com obj['NS']['USER'], self.isolation.getns('user'), 'user set' 2321182St.nateldemoura@f5.com ) 2331182St.nateldemoura@f5.com 2341182St.nateldemoura@f5.com def test_isolation_pid(self): 2351182St.nateldemoura@f5.com if not self.isolation_key('pid'): 2361182St.nateldemoura@f5.com print('pid namespace is not supported') 2371182St.nateldemoura@f5.com raise unittest.SkipTest() 2381182St.nateldemoura@f5.com 239*1307St.nateldemoura@f5.com if not (self.is_su or self.isolation_key('unprivileged_userns_clone')): 240*1307St.nateldemoura@f5.com print('requires root or unprivileged_userns_clone') 2411182St.nateldemoura@f5.com raise unittest.SkipTest() 2421182St.nateldemoura@f5.com 243*1307St.nateldemoura@f5.com self.load( 244*1307St.nateldemoura@f5.com 'ns_inspect', 245*1307St.nateldemoura@f5.com isolation={'namespaces': {'pid': True, 'credential': True}}, 246*1307St.nateldemoura@f5.com ) 2471182St.nateldemoura@f5.com 2481296St.nateldemoura@f5.com obj = self.getjson()['body'] 2491182St.nateldemoura@f5.com 2501182St.nateldemoura@f5.com self.assertEqual(obj['PID'], 1, 'pid of container is 1') 2511182St.nateldemoura@f5.com 2521236St.nateldemoura@f5.com def test_isolation_namespace_false(self): 2531236St.nateldemoura@f5.com self.load('ns_inspect') 2541236St.nateldemoura@f5.com allns = list(self.available['features']['isolation'].keys()) 2551236St.nateldemoura@f5.com 2561236St.nateldemoura@f5.com remove_list = ['unprivileged_userns_clone', 'ipc', 'cgroup'] 2571236St.nateldemoura@f5.com allns = [ns for ns in allns if ns not in remove_list] 2581236St.nateldemoura@f5.com 2591236St.nateldemoura@f5.com namespaces = {} 2601236St.nateldemoura@f5.com for ns in allns: 2611236St.nateldemoura@f5.com if ns == 'user': 2621236St.nateldemoura@f5.com namespaces['credential'] = False 2631236St.nateldemoura@f5.com elif ns == 'mnt': 2641236St.nateldemoura@f5.com namespaces['mount'] = False 2651236St.nateldemoura@f5.com elif ns == 'net': 2661236St.nateldemoura@f5.com namespaces['network'] = False 2671236St.nateldemoura@f5.com elif ns == 'uts': 2681236St.nateldemoura@f5.com namespaces['uname'] = False 2691236St.nateldemoura@f5.com else: 2701236St.nateldemoura@f5.com namespaces[ns] = False 2711236St.nateldemoura@f5.com 272*1307St.nateldemoura@f5.com self.load('ns_inspect', isolation={'namespaces': namespaces}) 2731236St.nateldemoura@f5.com 2741296St.nateldemoura@f5.com obj = self.getjson()['body'] 2751236St.nateldemoura@f5.com 2761236St.nateldemoura@f5.com for ns in allns: 2771236St.nateldemoura@f5.com if ns.upper() in obj['NS']: 2781236St.nateldemoura@f5.com self.assertEqual( 2791236St.nateldemoura@f5.com obj['NS'][ns.upper()], 2801236St.nateldemoura@f5.com self.available['features']['isolation'][ns], 2811236St.nateldemoura@f5.com '%s match' % ns, 2821236St.nateldemoura@f5.com ) 2831236St.nateldemoura@f5.com 2841182St.nateldemoura@f5.com 2851182St.nateldemoura@f5.comif __name__ == '__main__': 2861182St.nateldemoura@f5.com TestGoIsolation.main() 287