| 25 | #[tonic::async_trait] |
| 26 | impl TenantService for Tenant { |
| 27 | async fn create( |
| 28 | &self, |
| 29 | request: Request<api::CreateTenantRequest>, |
| 30 | ) -> Result<Response<api::CreateTenantResponse>, Status> { |
| 31 | self.validator |
| 32 | .validate( |
| 33 | request.extensions(), |
| 34 | validator::ValidateTenantsAccess::new(validator::Flag::Create), |
| 35 | ) |
| 36 | .await?; |
| 37 | |
| 38 | let req_tenant = match &request.get_ref().tenant { |
| 39 | Some(v) => v, |
| 40 | None => { |
| 41 | return Err(Status::invalid_argument("tenant is missing")); |
| 42 | } |
| 43 | }; |
| 44 | |
| 45 | // Decode prefixes |
| 46 | let mut dev_addr_prefixes = vec![]; |
| 47 | for p in &req_tenant.dev_addr_prefixes { |
| 48 | let prefix = DevAddrPrefix::from_str(p).map_err(|e| { |
| 49 | Status::invalid_argument(format!("Invalid DevAddr prefix: {}, error: {}", p, e)) |
| 50 | })?; |
| 51 | dev_addr_prefixes.push(Some(prefix)); |
| 52 | } |
| 53 | |
| 54 | let t = tenant::Tenant { |
| 55 | name: req_tenant.name.clone(), |
| 56 | description: req_tenant.description.clone(), |
| 57 | can_have_gateways: req_tenant.can_have_gateways, |
| 58 | max_device_count: req_tenant.max_device_count as i32, |
| 59 | max_gateway_count: req_tenant.max_gateway_count as i32, |
| 60 | private_gateways_up: req_tenant.private_gateways_up, |
| 61 | private_gateways_down: req_tenant.private_gateways_down, |
| 62 | tags: fields::KeyValue::new(req_tenant.tags.clone()), |
| 63 | dev_addr_prefixes: fields::DevAddrPrefixVec::new(dev_addr_prefixes), |
| 64 | ..Default::default() |
| 65 | }; |
| 66 | |
| 67 | let t = tenant::create(t).await.map_err(|e| e.status())?; |
| 68 | |
| 69 | let mut resp = Response::new(api::CreateTenantResponse { |
| 70 | id: t.id.to_string(), |
| 71 | }); |
| 72 | resp.metadata_mut() |
| 73 | .insert("x-log-tenant_id", t.id.to_string().parse().unwrap()); |
| 74 | |
| 75 | Ok(resp) |
| 76 | } |
| 77 | |
| 78 | async fn get( |
| 79 | &self, |