예제 #1
0
    def setup_upload_artifact_selection(self, plan, artifacts=()):
        tenant, username, password = self.get_tenant_username_and_password(
            plan=plan)
        auth_token = self.get_auth_token(username, password)

        api_client = ApiClient(deployments.URL_MGMT)
        api_client.headers = {}  # avoid default Content-Type: application/json
        api_client.with_auth(auth_token)

        # create and upload the mender artifact
        for artifact_kw in artifacts:
            artifact_kw.setdefault("artifact_name", "test")
            artifact_kw.setdefault("device_types", ["arm1"])
            with get_mender_artifact(**artifact_kw) as artifact:
                r = api_client.with_auth(auth_token).call(
                    "POST",
                    deployments.URL_DEPLOYMENTS_ARTIFACTS,
                    files=(
                        ("description", (None, "description")),
                        ("size", (None, str(os.path.getsize(artifact)))),
                        (
                            "artifact",
                            (
                                artifact,
                                open(artifact, "rb"),
                                "application/octet-stream",
                            ),
                        ),
                    ),
                )
            assert r.status_code == 201

        # create a new accepted device
        devauthd = ApiClient(deviceauth.URL_DEVICES)
        devauthm = ApiClient(deviceauth.URL_MGMT)
        dev = make_accepted_device(
            devauthd,
            devauthm,
            auth_token,
            tenant.tenant_token if tenant is not None else "",
        )
        assert dev is not None

        # create a deployment
        resp = api_client.with_auth(auth_token).call(
            "POST",
            deployments.URL_DEPLOYMENTS,
            body={
                "name": "deployment-1",
                "artifact_name": "test",
                "devices": [dev.id],
            },
        )
        assert resp.status_code == 201

        return dev
예제 #2
0
def make_deployment(token):
    depl_v1 = ApiClient(deployments_v1.URL_MGMT)

    uuidv4 = str(uuid.uuid4())
    artifact_name = "artifact-" + uuidv4
    name = "dep-" + uuidv4

    with get_mender_artifact(
            artifact_name=artifact_name,
            device_types=["arm1"],
    ) as artifact:
        r = depl_v1.with_auth(token).call(
            "POST",
            deployments_v1.URL_DEPLOYMENTS_ARTIFACTS,
            files=(
                ("description", (None, "description")),
                ("size", (None, str(os.path.getsize(artifact)))),
                (
                    "artifact",
                    (artifact, open(artifact,
                                    "rb"), "application/octet-stream"),
                ),
            ),
        )
    assert r.status_code == 201

    request_body = {
        "name": name,
        "artifact_name": artifact_name,
        "devices": ["arm1"],
    }
    resp = depl_v1.with_auth(token).call("POST",
                                         "/deployments",
                                         body=request_body)
    assert resp.status_code == 201

    depl_resp = depl_v1.with_auth(token).call("GET", "/deployments")

    depl_resp = depl_resp.json()

    found = [d for d in depl_resp if d["name"] == name]

    assert len(found) == 1

    return found[0]
예제 #3
0
    def test_upload_artifact_depends_provides_valid(self, mongo, clean_mongo,
                                                    plan):
        tenant, username, password = self.get_tenant_username_and_password(
            plan=plan)
        auth_token = self.get_auth_token(username, password)

        api_client = ApiClient(deployments.URL_MGMT)
        api_client.headers = {}  # avoid default Content-Type: application/json
        api_client.with_auth(auth_token)

        # create and upload the mender artifact
        with get_mender_artifact(
                artifact_name="test",
                device_types=["arm1"],
                depends=("key1:value1", "key2:value2"),
                provides=("key3:value3", "key4:value4", "key5:value5"),
        ) as artifact:
            r = api_client.with_auth(auth_token).call(
                "POST",
                deployments.URL_DEPLOYMENTS_ARTIFACTS,
                files=(
                    ("description", (None, "description")),
                    ("size", (None, str(os.path.getsize(artifact)))),
                    (
                        "artifact",
                        (artifact, open(artifact,
                                        "rb"), "application/octet-stream"),
                    ),
                ),
            )
        assert r.status_code == 201

        # extract the artifact id from the Location header
        artifact_id = r.headers.get("Location", "").rsplit("/", 1)[-1]
        assert artifact_id != ""

        # get the artifact details from the API
        artifact_url = deployments.URL_DEPLOYMENTS_ARTIFACTS_GET.replace(
            "{id}", artifact_id)
        r = api_client.call("GET", artifact_url)
        assert r.status_code == 200
        artifact = r.json()

        # artifact data assertions
        assert artifact is not None
        assert artifact["description"] == "description"
        assert artifact["name"] == "test"
        assert artifact["info"] == {"format": "mender", "version": 3}
        assert artifact["signed"] is False
        assert len(artifact["updates"]) == 1
        assert artifact["size"] > 0
        assert artifact["id"] is not None
        assert artifact["modified"] is not None
        assert artifact["artifact_depends"] == {
            "device_type": ["arm1"],
            "key1": "value1",
            "key2": "value2",
        }
        assert artifact["artifact_provides"] == {
            "artifact_name": "test",
            "key3": "value3",
            "key4": "value4",
            "key5": "value5",
        }
예제 #4
0
    def test_upload_artifact_depends_conflicting(self, mongo, clean_mongo):
        tenant, username, password = self.get_tenant_username_and_password(
            plan="os")
        auth_token = self.get_auth_token(username, password)

        api_client = ApiClient(deployments.URL_MGMT)
        api_client.headers = {}  # avoid default Content-Type: application/json
        api_client.with_auth(auth_token)

        # create and upload the mender artifact
        with get_mender_artifact(
                artifact_name="test",
                device_types=["arm1", "arm2"],
                depends=("key1:value1", "key2:value2"),
                provides=("key3:value3", "key4:value4", "key5:value5"),
        ) as artifact:
            r = api_client.with_auth(auth_token).call(
                "POST",
                deployments.URL_DEPLOYMENTS_ARTIFACTS,
                files=(
                    ("description", (None, "description")),
                    ("size", (None, str(os.path.getsize(artifact)))),
                    (
                        "artifact",
                        (artifact, open(artifact,
                                        "rb"), "application/octet-stream"),
                    ),
                ),
            )
        assert r.status_code == 201

        # create and upload a conflicting mender artifact
        # conflict because (arm2 / key:value1 / key:value2) are duplicated
        with get_mender_artifact(
                artifact_name="test",
                device_types=["arm2", "arm3"],
                depends=("key1:value1", "key2:value2"),
                provides=("key3:value3", "key4:value4", "key5:value5"),
        ) as artifact:
            r = api_client.with_auth(auth_token).call(
                "POST",
                deployments.URL_DEPLOYMENTS_ARTIFACTS,
                files=(
                    ("description", (None, "description")),
                    ("size", (None, str(os.path.getsize(artifact)))),
                    (
                        "artifact",
                        (artifact, open(artifact,
                                        "rb"), "application/octet-stream"),
                    ),
                ),
            )
        assert r.status_code == 409

        # create and upload a non-conflicting mender artifact
        with get_mender_artifact(
                artifact_name="test",
                device_types=["arm4"],
                depends=("key1:value1", "key2:value2"),
                provides=("key3:value3", "key4:value4", "key5:value5"),
        ) as artifact:
            r = api_client.with_auth(auth_token).call(
                "POST",
                deployments.URL_DEPLOYMENTS_ARTIFACTS,
                files=(
                    ("description", (None, "description")),
                    ("size", (None, str(os.path.getsize(artifact)))),
                    (
                        "artifact",
                        (artifact, open(artifact,
                                        "rb"), "application/octet-stream"),
                    ),
                ),
            )
        assert r.status_code == 201
예제 #5
0
    def test_artifacts_exclusive_to_user(self, mongo, clean_mongo):
        tenants = []
        #
        uuidv4 = str(uuid.uuid4())
        tenant, username, password = (
            "test.mender.io-" + uuidv4,
            "some.user+" + uuidv4 + "@example.com",
            "secretsecret",
        )
        tenant = create_org(tenant, username, password)
        tenants.append(tenant)
        #
        uuidv4 = str(uuid.uuid4())
        tenant, username, password = (
            "test.mender.io-" + uuidv4,
            "some.user+" + uuidv4 + "@example.com",
            "secretsecret",
        )
        tenant = create_org(tenant, username, password)
        tenants.append(tenant)

        api_client = ApiClient(deployments.URL_MGMT)
        api_client.headers = {}  # avoid default Content-Type: application/json

        for tenant in tenants:
            user = tenant.users[0]
            auth_token = self.get_auth_token(user.name, user.pwd)

            # create and upload the mender artifact
            with get_mender_artifact(
                    artifact_name=user.name,
                    device_types=["arm1"],
                    depends=("key1:value1", "key2:value2"),
                    provides=("key3:value3", "key4:value4", "key5:value5"),
            ) as artifact:
                r = api_client.with_auth(auth_token).call(
                    "POST",
                    deployments.URL_DEPLOYMENTS_ARTIFACTS,
                    files=(
                        ("description", (None, "description")),
                        ("size", (None, str(os.path.getsize(artifact)))),
                        (
                            "artifact",
                            (
                                artifact,
                                open(artifact, "rb"),
                                "application/octet-stream",
                            ),
                        ),
                    ),
                )
                assert r.status_code == 201

        for tenant in tenants:
            user = tenant.users[0]
            auth_token = self.get_auth_token(user.name, user.pwd)
            api_client.with_auth(auth_token)
            r = api_client.call("GET", deployments.URL_DEPLOYMENTS_ARTIFACTS)
            assert r.status_code == 200
            artifacts = [
                artifact for artifact in r.json()
                if not artifact["name"].startswith("mender-demo-artifact")
            ]
            assert len(artifacts) == 1
            assert artifacts[0]["name"] == user.name
예제 #6
0
def make_deployment(token: str, tenant_token: str) -> Tuple[Dict, Dict]:
    """Create sample deployment for test purposes."""
    depl_v1 = ApiClient(deployments_v1.URL_MGMT)

    uuidv4 = str(uuid.uuid4())
    artifact_name = "artifact-" + uuidv4
    name = "dep-" + uuidv4

    with get_mender_artifact(
            artifact_name=artifact_name,
            device_types=["arm1"],
    ) as artifact:
        r = depl_v1.with_auth(token).call(
            "POST",
            deployments_v1.URL_DEPLOYMENTS_ARTIFACTS,
            files=(
                ("description", (None, "description")),
                ("size", (None, str(os.path.getsize(artifact)))),
                (
                    "artifact",
                    (artifact, open(artifact,
                                    "rb"), "application/octet-stream"),
                ),
            ),
        )
    assert r.status_code == 201
    artifact = {"id": r.headers["Location"].rsplit("/", 1)[1]}

    # single device deployments will query the inventory service to
    # obtain the name of the groups the device belongs to; for this
    # reason, we need the device to be provisioned correctly both
    # in deviceauth and inventory
    dev = make_device_with_inventory(
        [{
            "name": "foo",
            "value": "foo"
        }],
        token,
        tenant_token,
    )

    request_body = {
        "name": name,
        "artifact_name": artifact_name,
        "devices": [dev.id],
    }
    resp = depl_v1.with_auth(token).call("POST",
                                         "/deployments",
                                         body=request_body)
    assert resp.status_code == 201

    depl_resp = depl_v1.with_auth(token).call("GET", "/deployments")

    depl_resp = depl_resp.json()

    found = [d for d in depl_resp if d["name"] == name]

    assert len(found) == 1
    deployment = found[0]

    return deployment, artifact