diff --git a/.github/workflows/install_test.yml b/.github/workflows/install_test.yml index 9f9f114a..ad3a2ca0 100644 --- a/.github/workflows/install_test.yml +++ b/.github/workflows/install_test.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/install_test_coverage.yml b/.github/workflows/install_test_coverage.yml index 4117531a..2e239147 100644 --- a/.github/workflows/install_test_coverage.yml +++ b/.github/workflows/install_test_coverage.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/install_test_setup_py.yml b/.github/workflows/install_test_setup_py.yml index b89c1767..039daf9f 100644 --- a/.github/workflows/install_test_setup_py.yml +++ b/.github/workflows/install_test_setup_py.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/pylint_and_mypy.yml b/.github/workflows/pylint_and_mypy.yml index a0b12692..3f967b75 100644 --- a/.github/workflows/pylint_and_mypy.yml +++ b/.github/workflows/pylint_and_mypy.yml @@ -12,10 +12,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.12 - name: Install poetry run: | python -m pip install poetry diff --git a/.github/workflows/pypi_push.yml b/.github/workflows/pypi_push.yml index 7500de48..b54c3c5a 100644 --- a/.github/workflows/pypi_push.yml +++ b/.github/workflows/pypi_push.yml @@ -8,10 +8,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - - name: Set up Python 3.8 🐍🐍🐍 + - name: Set up Python 3.12 🐍🐍🐍 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.12 - name: Install poetry run: | python -m pip install poetry diff --git a/libcloudforensics/providers/gcp/internal/compute.py b/libcloudforensics/providers/gcp/internal/compute.py index 4cca541e..f447feb0 100644 --- a/libcloudforensics/providers/gcp/internal/compute.py +++ b/libcloudforensics/providers/gcp/internal/compute.py @@ -1382,10 +1382,16 @@ def GetBootDisk(self) -> 'GoogleComputeDisk': Raises: ResourceNotFoundError: If no boot disk could be found. + InvalidNameError: If the boot disk Source could not be found. """ for disk in self.GetValue('disks'): if disk['boot']: + if 'source' not in disk: + raise errors.InvalidNameError( + 'Boot disk has no source attribute: {0:s}'.format( + self.name), + __name__) disk_name = disk['source'].split('/')[-1] return GoogleCloudCompute(self.project_id).GetDisk(disk_name=disk_name) raise errors.ResourceNotFoundError( @@ -1406,7 +1412,7 @@ def GetDisk(self, disk_name: str) -> 'GoogleComputeDisk': """ for disk in self.GetValue('disks'): - if disk['source'].split('/')[-1] == disk_name: + if disk.get('source', '').split('/')[-1] == disk_name: return GoogleCloudCompute(self.project_id).GetDisk(disk_name=disk_name) raise errors.ResourceNotFoundError( 'Disk {0:s} was not found in instance {1:s}'.format( @@ -1423,7 +1429,9 @@ def ListDisks(self) -> Dict[str, 'GoogleComputeDisk']: disks = {} disk_names = [ - disk['source'].split('/')[-1] for disk in self.GetValue('disks') + disk['source'].split('/')[-1] + for disk in self.GetValue('disks') + if disk.get('source', None) ] for name in disk_names: disks[name] = self.GetDisk(name) @@ -1507,7 +1515,7 @@ def DetachDisk(self, disk: 'GoogleComputeDisk') -> None: gce_instance_client = self.GceApi().instances() # pylint: disable=no-member device_name = None for disk_dict in self.GetValue('disks'): - if disk_dict['source'].split('/')[-1] == disk.name: + if disk_dict.get('source', '').split('/')[-1] == disk.name: device_name = disk_dict['deviceName'] request = gce_instance_client.detachDisk( instance=self.name, @@ -1541,7 +1549,9 @@ def Delete( disks_to_delete = [] if delete_disks: disks_to_delete = [ - disk['source'].split('/')[-1] for disk in self.GetValue('disks') + disk['source'].split('/')[-1] + for disk in self.GetValue('disks') + if disk.get('source', None) ] gce_instance_client = self.GceApi().instances() # pylint: disable=no-member diff --git a/poetry.lock b/poetry.lock index 2d96c09e..bc8dc8d5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "adal" @@ -237,9 +237,6 @@ files = [ {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] @@ -1497,17 +1494,6 @@ files = [ [package.dependencies] six = ">=1.5" -[[package]] -name = "pytz" -version = "2024.2" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, - {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, -] - [[package]] name = "pywin32" version = "308" @@ -1667,6 +1653,26 @@ botocore = ">=1.33.2,<2.0a.0" [package.extras] crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] +[[package]] +name = "setuptools" +version = "75.8.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.9" +files = [ + {file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"}, + {file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] + [[package]] name = "six" version = "1.16.0" @@ -2153,5 +2159,5 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" -python-versions = "^3.8" -content-hash = "b304030f8ae430745736ae7614169b407c716fef2b5bbd66eef8fc5c9b16c281" +python-versions = "^3.9" +content-hash = "01322dba7efbd1e2982c3290f375d143b4d13e77fb9f0c8a0452282a3c4d9040" diff --git a/pyproject.toml b/pyproject.toml index 9e9fbd3f..ddb57552 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ readme = "README.md" cloudforensics = "tools.cli:Main" [tool.poetry.dependencies] -python = "^3.8" +python = "^3.9" google-api-core = "*" azure-common = "^1.1.28" azure-core = "^1.29.4" @@ -40,6 +40,7 @@ urllib3 = [ {version = ">=1.25.4,<2.1", python = ">=3.10"} ] google-auth = "^2.22.0" +setuptools = "^75.8.0" [tool.poetry.group.dev.dependencies] coverage = "^7.2.7" diff --git a/tests/providers/gcp/gcp_mocks.py b/tests/providers/gcp/gcp_mocks.py index 06e868b6..df227cea 100644 --- a/tests/providers/gcp/gcp_mocks.py +++ b/tests/providers/gcp/gcp_mocks.py @@ -240,6 +240,18 @@ 'initializeParams': { 'diskName': FAKE_DISK.name } + }, + { + 'kind': 'compute#attachedDisk', + 'type': 'SCRATCH', + 'mode': 'READ_WRITE', + 'savedState': 'DISK_SAVED_STATE_UNSPECIFIED', + 'deviceName': 'local-ssd-0', + 'index': 1, + 'boot': False, + 'autoDelete': True, + 'interface': 'NVME', + 'diskSizeGb': '375' }], 'networkInterfaces': MOCK_NETWORK_INTERFACES, 'metadata': {