nethsm_tests/
container.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use nethsm::Url;
use rustainers::{
    ExposedPort,
    ImageName,
    RunnableContainer,
    RunnableContainerBuilder,
    ToRunnableContainer,
    WaitStrategy,
};
use testresult::TestResult;
use uuid::{timestamp::Timestamp, NoContext, Uuid};

/// The NetHSM container image and specific tag
///
/// We are currently pinning to "c16fe4ed" due to <https://gitlab.archlinux.org/archlinux/signstar/-/issues/32>
/// In the future we will probably want to stick to a specific release tag (representing an actual
/// upstream release) and not "testing"
const IMAGE_NAME: &str = "docker.io/nitrokey/nethsm:c16fe4ed";
const DEFAULT_PORT: u16 = 8443;
const DEFAULT_PATH: &str = "/api/v1";

/// An image of NetHSM used to create a running container.
#[derive(Debug)]
pub struct NetHsmImage {
    /// Image name that is used to start the container.
    pub image: ImageName,

    /// Exposed port which will be used for communication with the NetHSM.
    pub port: ExposedPort,
}

impl NetHsmImage {
    /// Returns an base URL for the virtualized NetHSM.
    pub async fn url(&self) -> TestResult<Url> {
        Ok(Url::new(&format!(
            "https://localhost:{}{}",
            self.port.host_port().await?,
            DEFAULT_PATH
        ))?)
    }
}

impl Default for NetHsmImage {
    fn default() -> Self {
        Self {
            image: ImageName::new(IMAGE_NAME),
            port: ExposedPort::new(DEFAULT_PORT),
        }
    }
}

impl ToRunnableContainer for NetHsmImage {
    fn to_runnable(&self, builder: RunnableContainerBuilder) -> RunnableContainer {
        builder
            .with_image(self.image.clone())
            .with_container_name(Some(format!(
                "nethsm-test-{}",
                Uuid::new_v7(Timestamp::now(NoContext))
            )))
            .with_wait_strategy(WaitStrategy::HttpSuccess {
                https: true,
                require_valid_certs: false,
                path: "/".into(),
                container_port: 8443.into(),
            })
            .with_port_mappings([self.port.clone()])
            .build()
    }
}