Skip to content
This repository was archived by the owner on Aug 20, 2025. It is now read-only.

Commit 552f7ca

Browse files
authored
Merge pull request #102 from carlosmmatos/minor-updates
fix: update auth for podman login + minor fixes
2 parents 7528b4c + 798dbb7 commit 552f7ca

File tree

2 files changed

+61
-42
lines changed

2 files changed

+61
-42
lines changed

README.md

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,44 @@ A CrowdStrike [OAuth2 API keys](https://falcon.crowdstrike.com/support/api-clien
2727

2828
## Installation
2929

30-
### For Docker Only
30+
Choose ONE of the following installation methods based on your container runtime:
31+
32+
### Option 1: Docker Installation
33+
34+
If you're using Docker:
3135

3236
```shell
3337
pip3 install docker crowdstrike-falconpy retry
3438
```
3539

36-
### For Podman Only
40+
### Option 2: Podman Installation
41+
42+
If you're using Podman:
3743

3844
```shell
3945
pip3 install podman crowdstrike-falconpy retry
4046
```
4147

42-
> [!WARNING]
43-
>
44-
> The following command only needs to be executed if running podman as root:
45-
>
46-
> ```shell
47-
> export CONTAINER_HOST="unix:///var/run/podman/podman.sock"
48-
> ```
48+
#### Important Podman Configuration Notes
49+
50+
1. For ***rootless*** Podman, ensure the podman socket is running:
51+
52+
```shell
53+
systemctl --user start podman.socket
54+
```
55+
56+
2. For ***rootful*** Podman, Set the container host environment variable:
57+
58+
```shell
59+
export CONTAINER_HOST="unix:///var/run/podman/podman.sock"
60+
```
61+
62+
### Option 3: Complete Installation
4963

50-
### Complete Installation (requirements.txt)
64+
To install support for both Docker and Podman:
5165

5266
> [!NOTE]
53-
> Using the requirements.txt file will install both Docker and Podman python packages along with
54-
> any other dependency.
67+
> If using Podman, follow the [Podman Configuration Notes](#important-podman-configuration-notes) above after installing the requirements.
5568
5669
```shell
5770
pip3 install -r requirements.txt
@@ -94,11 +107,11 @@ required arguments:
94107
>
95108
> `FALCON_CLIENT_ID`, `FALCON_CLIENT_SECRET`, and `FALCON_CLOUD_REGION`.
96109
>
97-
> Establishing and retrieving API credentials can be performed at https://falcon.crowdstrike.com/support/api-clients-and-keys.
110+
> Establishing and retrieving API credentials can be performed at <https://falcon.crowdstrike.com/support/api-clients-and-keys>.
98111
99112
## Example Scans
100113

101-
### Example 1:
114+
### Example 1
102115

103116
```shell
104117
python cs_scanimage.py --clientid FALCON_CLIENT_ID --repo <repo> --tag <tag> --cloud-region <cloud_region>
@@ -119,7 +132,7 @@ WARNING Alert: Misconfiguration found
119132
INFO Vulnerability score threshold not met: '0' out of '500'
120133
```
121134
122-
### Example 2:
135+
### Example 2
123136
124137
The script provided was built to score vulnerabilities on a scale show below.
125138

cs_scanimage.py

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import sys
4343
from os import environ as env
4444
from enum import Enum
45-
import subprocess # nosec
4645
import time
4746
import getpass
4847
from falconpy import FalconContainer, ContainerBaseURL
@@ -58,16 +57,18 @@
5857
class ScanImage(Exception):
5958
"""Scanning Image Tasks"""
6059

60+
# pylint:disable=too-many-instance-attributes
6161
def __init__(
6262
self, client_id, client_secret, repo, tag, client, runtime, cloud
63-
): # pylint: disable=too-many-positional-arguments
63+
): # pylint:disable=too-many-positional-arguments
6464
self.client_id = client_id
6565
self.client_secret = client_secret
6666
self.repo = repo
6767
self.tag = tag
6868
self.client = client
6969
self.runtime = runtime
7070
self.server_domain = ContainerBaseURL[cloud.replace("-", "").upper()].value
71+
self.auth_config = None
7172

7273
# Step 1: perform container tag to the registry corresponding to the cloud entered
7374
def container_tag(self):
@@ -104,23 +105,18 @@ def container_login(self):
104105
log.error("Docker login failed: %s", str(e))
105106
raise
106107
else: # podman
107-
command = ["podman", "login"]
108-
command.extend(["--username", self.client_id])
109-
command.extend(["--password", self.client_secret])
110-
command.append(self.server_domain)
111108
try:
112-
result = subprocess.run(
113-
command,
114-
shell=False, # nosec
115-
encoding="utf-8",
116-
stdout=subprocess.PIPE,
117-
stderr=subprocess.PIPE,
118-
check=True,
119-
)
120-
log.info(result.stdout.strip())
121-
except subprocess.CalledProcessError as e:
122-
log.error("Podman login failed: %s", e.stderr)
123-
raise RuntimeError(e.stderr.strip()) from None
109+
auth_config = {
110+
"username": self.client_id,
111+
"password": self.client_secret,
112+
}
113+
response = self.client.login(registry=self.server_domain, **auth_config)
114+
# Store auth config for subsequent operations
115+
self.auth_config = auth_config
116+
log.info(response["Status"])
117+
except Exception as e:
118+
log.error("Podman login failed: %s", str(e))
119+
raise
124120

125121
# Step 3: perform container push using the repo and tag supplied
126122
@retry(TimeoutError, tries=5, delay=5)
@@ -133,8 +129,12 @@ def container_push(self):
133129
image_push = self.client.images.push(
134130
image_str, stream=True, decode=True
135131
)
136-
else:
137-
image_push = self.client.images.push(image_str, stream=True)
132+
else: # podman
133+
image_push = self.client.images.push(
134+
image_str,
135+
stream=True,
136+
auth_config=getattr(self, "auth_config", None),
137+
)
138138

139139
for line in image_push:
140140
if isinstance(line, str):
@@ -162,7 +162,7 @@ def container_push(self):
162162
# Step 4: poll and get scanreport for specified amount of retries
163163
def get_scanreport(
164164
client_id, client_secret, cloud, user_agent, repo, tag, retry_count
165-
): # pylint: disable=too-many-positional-arguments
165+
): # pylint:disable=too-many-positional-arguments
166166
log.info("Downloading Image Scan Report")
167167
falcon = FalconContainer(
168168
client_id=client_id,
@@ -474,33 +474,39 @@ def parse_args():
474474
def detect_container_runtime():
475475
"""Detect whether Docker or Podman is available and return the appropriate client"""
476476
try:
477-
import docker # pylint: disable=C0415
477+
import docker # pylint:disable=C0415
478478

479479
try:
480480
client = docker.from_env()
481481
client.ping()
482482
return client, "docker"
483483
except (docker.errors.APIError, docker.errors.DockerException):
484-
import podman # pylint: disable=C0415
484+
import podman # pylint:disable=C0415
485485

486486
client = podman.from_env()
487487
try:
488488
client.ping()
489489
except (ConnectionRefusedError, podman.errors.exceptions.APIError) as exc:
490490
raise RuntimeError(
491-
"Could not connect to Podman socket, double check the CONTAINER_HOST environment variable."
491+
"Could not connect to Podman socket. "
492+
"If running rootless, ensure your podman.socket is running (systemctl --user start podman.socket). "
493+
"If running as root, ensure the CONTAINER_HOST environment variable is set correctly "
494+
"(e.g. unix:///var/run/podman/podman.sock)."
492495
) from exc
493496
return client, "podman"
494497
except ImportError:
495498
try:
496-
import podman # pylint: disable=C0415
499+
import podman # pylint:disable=C0415
497500

498501
client = podman.from_env()
499502
try:
500503
client.ping()
501504
except (ConnectionRefusedError, podman.errors.exceptions.APIError) as exc:
502505
raise RuntimeError(
503-
"Could not connect to Podman socket, double check the CONTAINER_HOST environment variable."
506+
"Could not connect to Podman socket. "
507+
"If running rootless, ensure your podman.socket is running (systemctl --user start podman.socket). "
508+
"If running as root, ensure the CONTAINER_HOST environment variable is set correctly "
509+
"(e.g. unix:///var/run/podman/podman.sock)."
504510
) from exc
505511
return client, "podman"
506512
except ImportError as exc:
@@ -509,7 +515,7 @@ def detect_container_runtime():
509515
) from exc
510516

511517

512-
def main(): # pylint: disable=R0915
518+
def main(): # pylint:disable=R0915
513519

514520
try:
515521
(

0 commit comments

Comments
 (0)