xref: /unit/test/test_go_isolation.py (revision 1293)
1*1293St.nateldemoura@f5.comimport pwd
2*1293St.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
351182St.nateldemoura@f5.com        obj = self.isolation.parsejson(self.get()['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')
49*1293St.nateldemoura@f5.com
50*1293St.nateldemoura@f5.com        user_id = pwd.getpwnam('nobody').pw_uid
51*1293St.nateldemoura@f5.com
52*1293St.nateldemoura@f5.com        try:
53*1293St.nateldemoura@f5.com            group_id = grp.getgrnam('nogroup').gr_gid
54*1293St.nateldemoura@f5.com        except:
55*1293St.nateldemoura@f5.com            group_id = grp.getgrnam('nobody').gr_gid
56*1293St.nateldemoura@f5.com
571182St.nateldemoura@f5.com        obj = self.isolation.parsejson(self.get()['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')
61*1293St.nateldemoura@f5.com
62*1293St.nateldemoura@f5.com        if self.is_su:
63*1293St.nateldemoura@f5.com            self.assertEqual(obj['UID'], user_id, 'uid match')
64*1293St.nateldemoura@f5.com            self.assertEqual(obj['GID'], group_id, 'gid match')
65*1293St.nateldemoura@f5.com        else:
66*1293St.nateldemoura@f5.com            self.assertEqual(obj['UID'], self.uid, 'uid match')
67*1293St.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
711182St.nateldemoura@f5.com        obj = self.isolation.parsejson(self.get()['body'])
721182St.nateldemoura@f5.com
731182St.nateldemoura@f5.com        # default uid and gid maps current user to nobody
74*1293St.nateldemoura@f5.com        self.assertEqual(obj['UID'], user_id, 'uid nobody')
75*1293St.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": [
81*1293St.nateldemoura@f5.com                    {"container": user_id, "host": self.uid, "size": 1}
821182St.nateldemoura@f5.com                ],
831182St.nateldemoura@f5.com                "gidmap": [
84*1293St.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
891182St.nateldemoura@f5.com        obj = self.isolation.parsejson(self.get()['body'])
901182St.nateldemoura@f5.com
91*1293St.nateldemoura@f5.com        self.assertEqual(obj['UID'], user_id, 'uid match')
92*1293St.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
1081182St.nateldemoura@f5.com        obj = self.isolation.parsejson(self.get()['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
1421182St.nateldemoura@f5.com        obj = self.isolation.parsejson(self.get()['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
1681236St.nateldemoura@f5.com        obj = self.isolation.parsejson(self.get()['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