diff --git a/crates/faas-containerd/src/impls/cni/mod.rs b/crates/faas-containerd/src/impls/cni/mod.rs index abf234e..2a20596 100644 --- a/crates/faas-containerd/src/impls/cni/mod.rs +++ b/crates/faas-containerd/src/impls/cni/mod.rs @@ -9,30 +9,30 @@ use gateway::types::function::Query; #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub struct Endpoint { - pub service: String, + pub function_name: String, pub namespace: String, } impl Endpoint { - pub fn new(service: &str, namespace: &str) -> Self { + pub fn new(function_name: &str, namespace: &str) -> Self { Self { - service: service.to_string(), + function_name: function_name.to_string(), namespace: namespace.to_string(), } } } -/// format `-` as netns name, also the identifier of each function +/// format `-` as netns name, also the identifier of each function impl std::fmt::Display for Endpoint { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}-{}", self.namespace, self.service) + write!(f, "{}-{}", self.namespace, self.function_name) } } impl From for Endpoint { fn from(query: Query) -> Self { Self { - service: query.service, + function_name: query.function_name, namespace: query .namespace .unwrap_or(consts::DEFAULT_FUNCTION_NAMESPACE.to_string()), diff --git a/crates/faas-containerd/src/impls/container.rs b/crates/faas-containerd/src/impls/container.rs index eaaef45..2f92bf4 100644 --- a/crates/faas-containerd/src/impls/container.rs +++ b/crates/faas-containerd/src/impls/container.rs @@ -24,7 +24,7 @@ impl ContainerdService { metadata: &ContainerStaticMetadata, ) -> Result { let container = Container { - id: metadata.endpoint.service.clone(), + id: metadata.endpoint.function_name.clone(), image: metadata.image.clone(), runtime: Some(Runtime { name: "io.containerd.runc.v2".to_string(), @@ -35,7 +35,7 @@ impl ContainerdService { ContainerError::Internal })?), snapshotter: crate::consts::DEFAULT_SNAPSHOTTER.to_string(), - snapshot_key: metadata.endpoint.service.clone(), + snapshot_key: metadata.endpoint.function_name.clone(), ..Default::default() }; @@ -58,7 +58,7 @@ impl ContainerdService { /// 删除容器 pub async fn delete_container(&self, endpoint: &Endpoint) -> Result<(), ContainerError> { let Endpoint { - service: cid, + function_name: cid, namespace: ns, } = endpoint; let mut cc = self.client.containers(); @@ -79,7 +79,7 @@ impl ContainerdService { let mut cc = self.client.containers(); let request = GetContainerRequest { - id: endpoint.service.clone(), + id: endpoint.function_name.clone(), }; let resp = cc diff --git a/crates/faas-containerd/src/impls/function.rs b/crates/faas-containerd/src/impls/function.rs index 9e5da33..e6daf4f 100644 --- a/crates/faas-containerd/src/impls/function.rs +++ b/crates/faas-containerd/src/impls/function.rs @@ -15,7 +15,7 @@ impl From for ContainerStaticMetadata { ContainerStaticMetadata { image: info.image, endpoint: Endpoint::new( - &info.service, + &info.function_name, &info .namespace .unwrap_or(consts::DEFAULT_FUNCTION_NAMESPACE.to_string()), diff --git a/crates/faas-containerd/src/impls/snapshot.rs b/crates/faas-containerd/src/impls/snapshot.rs index 7526e46..539aa51 100644 --- a/crates/faas-containerd/src/impls/snapshot.rs +++ b/crates/faas-containerd/src/impls/snapshot.rs @@ -42,7 +42,7 @@ impl ContainerdService { .get_parent_snapshot(&container.image, &container.endpoint.namespace) .await?; self.do_prepare_snapshot( - &container.endpoint.service, + &container.endpoint.function_name, &container.endpoint.namespace, parent_snapshot, ) @@ -117,7 +117,7 @@ impl ContainerdService { let mut sc = self.client.snapshots(); let req = RemoveSnapshotRequest { snapshotter: crate::consts::DEFAULT_SNAPSHOTTER.to_string(), - key: endpoint.service.clone(), + key: endpoint.function_name.clone(), }; sc.remove(with_namespace!(req, endpoint.namespace)) .await diff --git a/crates/faas-containerd/src/impls/spec.rs b/crates/faas-containerd/src/impls/spec.rs index 9de071c..c0128af 100644 --- a/crates/faas-containerd/src/impls/spec.rs +++ b/crates/faas-containerd/src/impls/spec.rs @@ -312,7 +312,7 @@ impl ContainerdService { let spec = generate_default_unix_spec( &metadata.endpoint.namespace, - &metadata.endpoint.service, + &metadata.endpoint.function_name, &rt_conf, )?; let spec_json = serde_json::to_string(&spec).map_err(|e| { diff --git a/crates/faas-containerd/src/impls/task.rs b/crates/faas-containerd/src/impls/task.rs index 128fee1..6aee3ae 100644 --- a/crates/faas-containerd/src/impls/task.rs +++ b/crates/faas-containerd/src/impls/task.rs @@ -60,7 +60,7 @@ impl ContainerdService { /// 创建并启动任务 pub async fn new_task(&self, mounts: Vec, endpoint: &Endpoint) -> Result<(), TaskError> { let Endpoint { - service: cid, + function_name: cid, namespace: ns, } = endpoint; // let mounts = self.get_mounts(cid, ns).await?; @@ -103,7 +103,7 @@ impl ContainerdService { pub async fn get_task(&self, endpoint: &Endpoint) -> Result { let Endpoint { - service: cid, + function_name: cid, namespace: ns, } = endpoint; let mut tc = self.client.tasks(); @@ -179,7 +179,7 @@ impl ContainerdService { /// 杀死并删除任务 pub async fn kill_task_with_timeout(&self, endpoint: &Endpoint) -> Result<(), TaskError> { let Endpoint { - service: cid, + function_name: cid, namespace: ns, } = endpoint; let kill_timeout = Duration::from_secs(5); diff --git a/crates/faas-containerd/src/provider/function/list.rs b/crates/faas-containerd/src/provider/function/list.rs index d5f104e..2eadd88 100644 --- a/crates/faas-containerd/src/provider/function/list.rs +++ b/crates/faas-containerd/src/provider/function/list.rs @@ -18,7 +18,7 @@ impl ContainerdProvider { let mut statuses: Vec = Vec::new(); for container in containers { let endpoint = Endpoint { - service: container.id.clone(), + function_name: container.id.clone(), namespace: namespace.clone(), }; let created_at = container.created_at.unwrap().to_string(); @@ -43,7 +43,7 @@ impl ContainerdProvider { // 大部分字段并未实现,使用None填充 let status = Status { - name: endpoint.service, + function_name: endpoint.function_name, namespace: Some(endpoint.namespace), image: container.image, env_process: None, diff --git a/crates/faas-containerd/src/provider/function/status.rs b/crates/faas-containerd/src/provider/function/status.rs index b04bc43..1a60e8e 100644 --- a/crates/faas-containerd/src/provider/function/status.rs +++ b/crates/faas-containerd/src/provider/function/status.rs @@ -45,7 +45,7 @@ impl ContainerdProvider { // 大部分字段并未实现,使用None填充 let status = Status { - name: container.id, + function_name: container.id, namespace: Some(endpoint.namespace), image: container.image, env_process: None, diff --git a/crates/faas-containerd/src/provider/function/update.rs b/crates/faas-containerd/src/provider/function/update.rs index 92a49a9..fb75181 100644 --- a/crates/faas-containerd/src/provider/function/update.rs +++ b/crates/faas-containerd/src/provider/function/update.rs @@ -8,7 +8,7 @@ use crate::provider::ContainerdProvider; impl ContainerdProvider { pub(crate) async fn _update(&self, param: Deployment) -> Result<(), UpdateError> { let function = Query { - service: param.service.clone(), + function_name: param.function_name.clone(), namespace: param.namespace.clone(), }; self._delete(function).await.map_err(|e| { diff --git a/crates/gateway/src/bootstrap/mod.rs b/crates/gateway/src/bootstrap/mod.rs index c16a504..c0c9a04 100644 --- a/crates/gateway/src/bootstrap/mod.rs +++ b/crates/gateway/src/bootstrap/mod.rs @@ -139,7 +139,7 @@ mod tests { let meta = ProxyQuery::from_str(&any).unwrap(); HttpResponse::Ok().body(format!( "{}|{}|{}", - meta.query.service, + meta.query.function_name, meta.query.namespace.unwrap_or_default(), meta.path )) diff --git a/crates/gateway/src/handlers/function.rs b/crates/gateway/src/handlers/function.rs index 21ee01f..7b11927 100644 --- a/crates/gateway/src/handlers/function.rs +++ b/crates/gateway/src/handlers/function.rs @@ -12,9 +12,9 @@ pub async fn deploy( provider: web::Data

, info: web::Json, ) -> Result { - let service = info.0.service.clone(); + let function_name = info.0.function_name.clone(); (*provider).deploy(info.0).await.map(|()| { - HttpResponse::Accepted().body(format!("function {} was created successfully", service)) + HttpResponse::Accepted().body(format!("function {} was created successfully", function_name)) }) } @@ -22,9 +22,9 @@ pub async fn update( provider: web::Data

, info: web::Json, ) -> Result { - let service = info.0.service.clone(); + let function_name = info.0.function_name.clone(); (*provider).update(info.0).await.map(|()| { - HttpResponse::Accepted().body(format!("function {} was updated successfully", service)) + HttpResponse::Accepted().body(format!("function {} was updated successfully", function_name)) }) } @@ -32,15 +32,15 @@ pub async fn delete( provider: web::Data

, info: web::Json, ) -> Result { - let service = info.0.function_name.clone(); + let function_name = info.0.function_name.clone(); let query = Query { - service: service.clone(), + function_name: function_name.clone(), namespace: Some(info.0.namespace), }; (*provider) .delete(query) .await - .map(|()| HttpResponse::Ok().body(format!("function {} was deleted successfully", service))) + .map(|()| HttpResponse::Ok().body(format!("function {} was deleted successfully", function_name))) } #[derive(Debug, Deserialize)] @@ -65,11 +65,11 @@ pub struct StatusParam { pub async fn status( provider: web::Data

, - name: web::Path, + function_name: web::Path, info: web::Query, ) -> Result { let query = Query { - service: name.into_inner(), + function_name: function_name.into_inner(), namespace: info.namespace.clone(), }; let status = (*provider).status(query).await?; diff --git a/crates/gateway/src/handlers/proxy.rs b/crates/gateway/src/handlers/proxy.rs index 80120dd..0c257a6 100644 --- a/crates/gateway/src/handlers/proxy.rs +++ b/crates/gateway/src/handlers/proxy.rs @@ -23,12 +23,12 @@ impl FromStr for ProxyQuery { } else { (path, "".to_owned()) }; - let (service, namespace) = identifier + let (function_name, namespace) = identifier .rsplit_once('.') .map(|(s, n)| (s.to_string(), Some(n.to_string()))) .unwrap_or((identifier.to_string(), None)); Ok(ProxyQuery { - query: Query { service, namespace }, + query: Query { function_name, namespace }, path: rest_path, }) } diff --git a/crates/gateway/src/types/function.rs b/crates/gateway/src/types/function.rs index 67de4e9..1e5c744 100644 --- a/crates/gateway/src/types/function.rs +++ b/crates/gateway/src/types/function.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; #[serde(rename_all = "camelCase")] pub struct Deployment { /// Service is the name of the function deployment - pub service: String, + pub function_name: String, /// Image is a fully-qualified container image pub image: String, @@ -73,7 +73,7 @@ pub struct Usage { #[serde(rename_all = "camelCase")] pub struct Status { /// The name of the function - pub name: String, + pub function_name: String, /// The fully qualified docker image name of the function pub image: String, @@ -128,7 +128,7 @@ pub struct Status { #[derive(Eq, Hash, PartialEq, Clone, Debug)] pub struct Query { /// Name of deployed function - pub service: String, + pub function_name: String, /// Namespace of deployed function pub namespace: Option, @@ -141,12 +141,12 @@ impl FromStr for Query { fn from_str(function_name: &str) -> Result { Ok(if let Some(index) = function_name.rfind('.') { Self { - service: function_name[..index].to_string(), + function_name: function_name[..index].to_string(), namespace: Some(function_name[index + 1..].to_string()), } } else { Self { - service: function_name.to_string(), + function_name: function_name.to_string(), namespace: Some("default".to_string()), } }) diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 74e173f..e73beb5 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -76,7 +76,29 @@ paths: description: Not Found '500': description: Internal Server Error - "/function/{function_name}": + update: + operationId: UpdateFunction + description: Update an existing function. + summary: Update an existing function. + tags: + - system + requestBody: + description: Function to update + content: + application/json: + schema: + "$ref": "#/components/schemas/FunctionDeployment" + required: true + responses: + '202': + description: Accepted + '400': + description: Bad Request + '404': + description: Not Found + '500': + description: Internal Server Error + "/function/{function_name_namespace}/{function_name}": post: operationId: InvokeFunction description: Invoke a function in the default namespace. @@ -87,12 +109,20 @@ paths: tags: - function parameters: - - name: function_name + - name: function_name_namespace in: path - description: Function name + description: Function name and namespace required: true schema: type: string + example: echo.test + - name: function_name + in: path + description: function_name + required: true + schema: + type: string + example: echo requestBody: description: "(Optional) data to pass to function" content: @@ -113,6 +143,76 @@ paths: description: Internal server error '503': description: Error Service Unavailable + "/auth/login": + post: + operationId: Login + description: Login to the system. + summary: Login to the system. + tags: + - internal + requestBody: + description: Credentials for login + content: + application/json: + schema: + "$ref": "#/components/schemas/Payload" + required: true + responses: + '200': + description: Successful login + content: + application/json: + schema: + type: object + required: [token,token_type] + properties: + token: + type: string + description: JWT token for authenticated requests + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... + token_type: + type: string + description: Type of the token + example: Bearer + '400': + description: Bad Request + '401': + description: Unauthorized + '500': + description: Internal server error + "/auth/register": + post: + operationId: Register + description: Register a new user. + summary: Register a new user. + tags: + - internal + requestBody: + description: User information for registration + content: + application/json: + schema: + "$ref": "#/components/schemas/Payload" + required: true + responses: + '201': + description: User registered successfully + content: + application/json: + schema: + type: object + required: [message, user_id] + properties: + message: + type: string + example: User created successfully + user_id: + type: string + example: "10086" + '409': + description: Conflict + '500': + description: Internal server error components: schemas: FunctionDeployment: @@ -189,4 +289,18 @@ components: type: object additionalProperties: type: string - description: environment variables for the function runtime \ No newline at end of file + description: environment variables for the function runtime + Payload: + type: object + required: + - username + - password + properties: + username: + type: string + description: Username for authentication + example: admin + password: + type: string + description: Password for authentication + example: password123 \ No newline at end of file