Skip to content

Commit

Permalink
GH-349: Extend service with a list app definitions endpoint
Browse files Browse the repository at this point in the history
### App definition endpoint
- Add AppDefinitionResource with endpoint to list all app definitions.
  The endpoint is restricted to authenticated users but is still available in anonymous mode

### Sensitive data redaction
- Add `SensitiveData` annotation to mark properties that should not be serialized publicly by Jackson.
- Add a corresponding serializer and serializer modifiert for Jackson and register the modifier in the service
- Add unit tests for the serializer

### Javascript API
- Update openapi.json from service
- Regenerate api code
- Add AppDefinitions namespace with function to list app definitions

### Testing Page
- Add button to get app definitions
- Apply formatting rules to App.tsx by saving it
- Minor fix in example keycloak URL to remove obsolete `/auth`

### Misc
- Add mockito dependency to the common maven module
  • Loading branch information
lucas-koehler committed Oct 22, 2024
1 parent 28dde63 commit 051f87a
Show file tree
Hide file tree
Showing 15 changed files with 1,012 additions and 65 deletions.
211 changes: 184 additions & 27 deletions documentation/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,54 @@
}
}
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
{
"SecurityScheme": []
}
]
}
},
"/service/appdefinition/{appId}": {
"get": {
"tags": ["App Definition Resource"],
"summary": "List app definitions",
"description": "List available app definitions.",
"parameters": [
{
"name": "appId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AppDefinitionSpec"
}
}
}
}
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -69,11 +112,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -106,11 +149,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -143,11 +186,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -191,11 +234,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -242,11 +285,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -281,11 +324,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -318,11 +361,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -369,11 +412,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand Down Expand Up @@ -409,11 +452,11 @@
}
}
},
"403": {
"description": "Not Allowed"
},
"401": {
"description": "Not Authorized"
},
"403": {
"description": "Not Allowed"
}
},
"security": [
Expand All @@ -426,6 +469,108 @@
},
"components": {
"schemas": {
"ActivityTracker": {
"type": "object",
"properties": {
"timeoutAfter": {
"format": "int32",
"type": "integer"
},
"notifyAfter": {
"format": "int32",
"type": "integer"
}
}
},
"AppDefinitionListRequest": {
"description": "A request to list available app definitions.",
"required": ["appId"],
"type": "object",
"properties": {
"appId": {
"description": "The App Id of this Theia Cloud instance. Request without a matching Id will be denied.",
"type": "string"
}
}
},
"AppDefinitionSpec": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"image": {
"type": "string"
},
"imagePullPolicy": {
"type": "string"
},
"pullSecret": {
"type": "string"
},
"uid": {
"format": "int32",
"type": "integer"
},
"port": {
"format": "int32",
"type": "integer"
},
"ingressname": {
"type": "string"
},
"minInstances": {
"format": "int32",
"type": "integer"
},
"maxInstances": {
"format": "int32",
"type": "integer"
},
"timeout": {
"format": "int32",
"type": "integer"
},
"requestsMemory": {
"type": "string"
},
"requestsCpu": {
"type": "string"
},
"limitsMemory": {
"type": "string"
},
"limitsCpu": {
"type": "string"
},
"downlinkLimit": {
"format": "int32",
"type": "integer"
},
"uplinkLimit": {
"format": "int32",
"type": "integer"
},
"mountPath": {
"type": "string"
},
"monitor": {
"$ref": "#/components/schemas/Monitor"
},
"options": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"ingressHostnamePrefixes": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"EnvironmentVars": {
"description": "An object to hold all the ways environment variables can be passed. Not to be used by itself.",
"type": "object",
Expand Down Expand Up @@ -498,6 +643,18 @@
}
}
},
"Monitor": {
"type": "object",
"properties": {
"port": {
"format": "int32",
"type": "integer"
},
"activityTracker": {
"$ref": "#/components/schemas/ActivityTracker"
}
}
},
"PingRequest": {
"description": "Request to ping the availability of the service.",
"required": ["appId"],
Expand Down
1 change: 1 addition & 0 deletions java/common/maven-conf/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<surefire-plugin.version>3.4.0</surefire-plugin.version>
<google.artifactregistry-maven-wagon-version>2.2.2</google.artifactregistry-maven-wagon-version>
<junit-jupiter.version>5.11.0</junit-jupiter.version>
<mockito.version>5.14.2</mockito.version>
<org.json.version>20240303</org.json.version>
<picocli.version>4.7.6</picocli.version>
<webhooks.framework.core.version>1.1.4</webhooks.framework.core.version>
Expand Down
7 changes: 7 additions & 0 deletions java/common/org.eclipse.theia.cloud.common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Map;

import org.eclipse.theia.cloud.common.k8s.resource.appdefinition.hub.AppDefinitionHub;
import org.eclipse.theia.cloud.common.serialization.SensitiveData;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
Expand All @@ -37,6 +38,7 @@ public class AppDefinitionSpec {
private String imagePullPolicy;

@JsonProperty("pullSecret")
@SensitiveData
private String pullSecret;

@JsonProperty("uid")
Expand Down Expand Up @@ -212,10 +214,11 @@ public List<String> getIngressHostnamePrefixes() {

@Override
public String toString() {
final String redactedPullSecret = "***";
return "AppDefinitionSpec [name=" + name + ", image=" + image + ", imagePullPolicy=" + imagePullPolicy
+ ", pullSecret=" + pullSecret + ", uid=" + uid + ", port=" + port + ", ingressname=" + ingressname
+ ", minInstances=" + minInstances + ", maxInstances=" + maxInstances + ", timeout=" + timeout
+ ", requestsMemory=" + requestsMemory + ", requestsCpu=" + requestsCpu + ", limitsMemory="
+ ", pullSecret=" + redactedPullSecret + ", uid=" + uid + ", port=" + port + ", ingressname="
+ ingressname + ", minInstances=" + minInstances + ", maxInstances=" + maxInstances + ", timeout="
+ timeout + ", requestsMemory=" + requestsMemory + ", requestsCpu=" + requestsCpu + ", limitsMemory="
+ limitsMemory + ", limitsCpu=" + limitsCpu + ", downlinkLimit=" + downlinkLimit + ", uplinkLimit="
+ uplinkLimit + ", mountPath=" + mountPath + "]";
}
Expand Down
Loading

0 comments on commit 051f87a

Please sign in to comment.