Skip to content

Commit

Permalink
Merge pull request #151 from sgherdao/feat-user-group-mgmt
Browse files Browse the repository at this point in the history
Feat user group mgmt
  • Loading branch information
xorrkaz authored Jun 22, 2024
2 parents e81069b + 450c5c8 commit b3bc0b8
Show file tree
Hide file tree
Showing 121 changed files with 1,376 additions and 239 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,8 @@ Network Trash Folder
Temporary Items
.apdisk
*.icloud

# virlutils test
5f0d96_inventory.ini
5f0d96_inventory.yaml
5f0d96_testbed.yaml
15 changes: 14 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,17 @@ With those settings, navigate to **View > Testing** in VSCode. The view should

### Code Style

Additionally, the code should follow any stylistic and architectural guidelines prescribed by the project. The project now uses [black](https://black.readthedocs.io/) to ensure consistent code formatting. When you installed the requirements_dev.txt in your virtual environment, it installed the `black` command. For each file that you are modifying, run `black ./virl/path/to/file.py` before you commit the file or submit a pull request.
Additionally, the code should follow any stylistic and architectural guidelines prescribed by the project. The project now uses [black](https://black.readthedocs.io/) and [isort](https://pycqa.github.io/isort/) to ensure consistent code formatting. When you installed the requirements_dev.txt in your virtual environment, it installed the `black` and `isort` commands. For each file that you are modifying, run the following before you commit the file or submit a pull request:

```sh
black ./virl/path/to/file.py
isort ./virl/path/to/file.py
```

### Linting

We use flake 8 to lint our code. Please keep the repository clean by running:

```sh
flake8
```
290 changes: 263 additions & 27 deletions README.md

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions examples/plugins/csv_inv.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from virl.api import GeneratorPlugin
import click
import csv
from virl.api import VIRLServer
from virl.helpers import get_current_lab, get_cml_client, safe_join_existing_lab, get_node_mgmt_ip

import click

from virl.api import GeneratorPlugin, VIRLServer
from virl.helpers import (get_cml_client, get_current_lab, get_node_mgmt_ip,
safe_join_existing_lab)


class CSVInventory(GeneratorPlugin, generator="csv"):
Expand Down
7 changes: 4 additions & 3 deletions examples/plugins/retitle_cmd.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from virl.api import CommandPlugin
import click
from virl.api import VIRLServer
from virl.helpers import get_cml_client, get_current_lab, safe_join_existing_lab

from virl.api import CommandPlugin, VIRLServer
from virl.helpers import (get_cml_client, get_current_lab,
safe_join_existing_lab)


class RetitleCommand(CommandPlugin, command="retitle"):
Expand Down
15 changes: 8 additions & 7 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
pip
Flask
Sphinx
black
bumpversion
wheel
watchdog
coverage
flake8
Flask
isort
pip
requests-mock
tox
coverage
Sphinx
twine
watchdog
wheel
white
requests-mock
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# coding: utf-8
from setuptools import setup, find_packages # noqa: H301
from setuptools import find_packages, setup # noqa: H301

from virl import __version__

NAME = "virlutils"
Expand Down
11 changes: 6 additions & 5 deletions tests/v2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import functools
import logging
import os
import unittest
from click.testing import CliRunner
from .mocks import MockCMLServer
import functools
import pdb
import sys
import traceback
import pdb
import unittest

import requests_mock
import respx
from click.testing import CliRunner
from httpx import Response
from virl2_client import ClientLibrary

from .mocks import MockCMLServer

# set to warning to hide unwanted HTTP requests
logger = logging.getLogger("httpx")
Expand Down
9 changes: 6 additions & 3 deletions tests/v2/bad_plugins.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from . import BaseCMLTest
from virl.api.plugin import _test_enable_plugins
from click.testing import CliRunner
import os

from click.testing import CliRunner

from virl.api.plugin import _test_enable_plugins

from . import BaseCMLTest

try:
from unittest.mock import patch
except ImportError:
Expand Down
6 changes: 4 additions & 2 deletions tests/v2/cluster.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import unittest
from . import BaseCMLTest, CLIENT_VERSION
from .mocks.github import MockGitHub # noqa

from click.testing import CliRunner

from . import CLIENT_VERSION, BaseCMLTest
from .mocks.github import MockGitHub # noqa

try:
from unittest.mock import patch
except ImportError:
Expand Down
3 changes: 2 additions & 1 deletion tests/v2/console.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from . import BaseCMLTest
from click.testing import CliRunner

from . import BaseCMLTest

try:
from unittest.mock import patch
except ImportError:
Expand Down
8 changes: 5 additions & 3 deletions tests/v2/definitions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from . import BaseCMLTest
from click.testing import CliRunner
import textwrap
import os
import textwrap
import traceback

from click.testing import CliRunner

from . import BaseCMLTest


class CMLDefinitionsTest(BaseCMLTest):

Expand Down
6 changes: 4 additions & 2 deletions tests/v2/down.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from . import BaseCMLTest
from click.testing import CliRunner
import os

from click.testing import CliRunner

from . import BaseCMLTest


class CMLTestDown(BaseCMLTest):
def setup_mocks(self, m):
Expand Down
6 changes: 4 additions & 2 deletions tests/v2/extract.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from . import BaseCMLTest
from click.testing import CliRunner
import os

from click.testing import CliRunner

from . import BaseCMLTest


class CMLExtractTests(BaseCMLTest):
def test_cml_extract(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/v2/generate_ansible.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from . import BaseCMLTest
from click.testing import CliRunner

from . import BaseCMLTest


class Tests(BaseCMLTest):
data = {
Expand Down
5 changes: 3 additions & 2 deletions tests/v2/generate_nso.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import requests_mock
from click.testing import CliRunner

from . import BaseCMLTest
from .mocks.nso import MockNSOServer
from click.testing import CliRunner
import requests_mock


class Tests(BaseCMLTest):
Expand Down
3 changes: 2 additions & 1 deletion tests/v2/generate_pyats.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from . import BaseCMLTest
from click.testing import CliRunner

from . import BaseCMLTest


class Tests(BaseCMLTest):
def test_virl_generate_pyats(self):
Expand Down
9 changes: 6 additions & 3 deletions tests/v2/good_plugins.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from . import BaseCMLTest
from virl.api.plugin import _test_enable_plugins
from click.testing import CliRunner
import os

from click.testing import CliRunner

from virl.api.plugin import _test_enable_plugins

from . import BaseCMLTest


class CMLGoodPluginTest(BaseCMLTest):
def setUp(self):
Expand Down
150 changes: 150 additions & 0 deletions tests/v2/groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
from click.testing import CliRunner

from . import BaseCMLTest


class TestCMLGroups(BaseCMLTest):
get_users = [
{
"id": "00000000-0000-4000-a000-000000000000",
"created": "2022-09-30T10:03:53+00:00",
"modified": "2024-06-21T15:16:42+00:00",
"username": "admin",
"fullname": "",
"email": "",
"description": "",
"admin": True,
"directory_dn": "",
"groups": [],
"labs": [],
"opt_in": True,
"resource_pool": None,
"tour_version": "2.6.1+build.11",
"pubkey_info": "",
},
{
"id": "9e4e75b4-aaab-47af-9edb-9364460a81ae",
"created": "2024-06-19T20:29:02+00:00",
"modified": "2024-06-21T10:42:20+00:00",
"username": "user",
"fullname": "",
"email": "",
"description": "",
"admin": False,
"directory_dn": "",
"groups": ["48c9c605-552f-4666-bd23-5b68cf4de665"],
"labs": [],
"opt_in": True,
"resource_pool": None,
"tour_version": "",
"pubkey_info": "",
},
]
post_groups = {
"id": "48c9c605-552f-4666-bd23-5b68cf4de665",
"created": "2024-02-29T21:44:13+00:00",
"modified": "2024-02-29T21:45:04+00:00",
"name": "group",
"description": "",
"members": ["00000000-0000-4000-a000-000000000000"],
"labs": [
{"id": "88119b68-9d08-40c4-90f5-6dc533fd0254", "permission": "read_write"},
],
}

patch_groups = post_groups

get_groups = [
{
"id": "48c9c605-552f-4666-bd23-5b68cf4de665",
"created": "2024-02-29T21:44:13+00:00",
"modified": "2024-02-29T21:45:04+00:00",
"name": "group",
"description": "",
"members": ["00000000-0000-4000-a000-000000000000"],
"labs": [
{"id": "88119b68-9d08-40c4-90f5-6dc533fd0254", "permission": "read_write"},
],
},
]

def test_cml_groups_ls(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "users", json=self.get_users)
self.setup_func("get", m, "groups", json=self.get_groups)
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "ls"])
self.assertEqual(0, result.exit_code)

def test_cml_groups_ls_verbose(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "users", json=self.get_users)
self.setup_func("get", m, "groups", json=self.get_groups)
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "ls", "--verbose"])
self.assertEqual(0, result.exit_code)

def test_cml_groups_create_group(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "users", json=self.get_users)
self.setup_func("post", m, "groups", json=self.post_groups)
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "create", "group"])
self.assertEqual(0, result.exit_code)

def test_cml_groups_create_group_fail(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "users", json=self.get_users)
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "create", "group"])
self.assertEqual(1, result.exit_code)

def test_cml_groups_update_group(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "users", json=self.get_users)
self.setup_func("get", m, "groups", json=self.get_groups)
self.setup_func("patch", m, "groups/48c9c605-552f-4666-bd23-5b68cf4de665", json=self.patch_groups)
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "update", "group"])
self.assertEqual(0, result.exit_code)

def test_cml_groups_update_group_fail(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "users", json=self.get_users)
self.setup_func("get", m, "groups", json=self.get_groups)
self.setup_func("patch", m, "groups/48c9c605-552f-4666-bd23-5b68cf4de665", json=self.patch_groups)
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "update", "nonexistent_group"])
self.assertEqual(1, result.exit_code)

def test_cml_groups_delete_group(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "groups", json=self.get_groups)
self.setup_func("delete", m, "groups/48c9c605-552f-4666-bd23-5b68cf4de665")
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "delete", "group"])
self.assertEqual(0, result.exit_code)

def test_cml_groups_delete_group_fail(self):
with self.get_context() as m:
self.setup_mocks(m)
self.setup_func("get", m, "groups", json=self.get_groups)
self.setup_func("delete", m, "groups/48c9c605-552f-4666-bd23-5b68cf4de665")
virl = self.get_virl()
runner = CliRunner()
result = runner.invoke(virl, ["groups", "delete", "nonexistent_group"])
self.assertEqual(1, result.exit_code)
3 changes: 2 additions & 1 deletion tests/v2/id.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from . import BaseCMLTest
from click.testing import CliRunner

from . import BaseCMLTest


class CMLIdTest(BaseCMLTest):
def test_cml_id(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/v2/ls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from . import BaseCMLTest
from click.testing import CliRunner

from . import BaseCMLTest


class TestCMLLs(BaseCMLTest):
def test_cml_ls_all(self):
Expand Down
Loading

0 comments on commit b3bc0b8

Please sign in to comment.