xref: /unit/test/test_go_isolation.py (revision 1236)
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