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
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]
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", }
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
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
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