-
Notifications
You must be signed in to change notification settings - Fork 0
feat: onboard serverupdate service #150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
d542a3d
Generate serverupdate
stackit-pipeline 131331e
add example
marceljk 98714cc
add changelog entries and version file
marceljk f8aa1df
review feedback: replace assert by Objects.requireNonNull
marceljk e5c10f5
Apply suggestions from code review
marceljk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| dependencies { | ||
| implementation project (':services:serverupdate') | ||
| implementation 'com.squareup.okhttp3:okhttp:4.12.0' | ||
| } | ||
|
|
||
| ext.mainClassName = 'cloud.stackit.sdk.serverupdate.examples.ServerUpdateExample' |
242 changes: 242 additions & 0 deletions
242
...rverupdate/src/main/java/cloud/stackit/sdk/serverupdate/examples/ServerUpdateExample.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,242 @@ | ||
| package cloud.stackit.sdk.serverupdate.examples; | ||
|
|
||
| import cloud.stackit.sdk.core.KeyFlowAuthenticator; | ||
| import cloud.stackit.sdk.core.config.CoreConfiguration; | ||
| import cloud.stackit.sdk.core.exception.ApiException; | ||
| import cloud.stackit.sdk.serverupdate.api.ServerUpdateApi; | ||
| import cloud.stackit.sdk.serverupdate.model.*; | ||
| import java.io.IOException; | ||
| import java.net.HttpURLConnection; | ||
| import java.time.Duration; | ||
| import java.util.Objects; | ||
| import java.util.UUID; | ||
| import java.util.concurrent.TimeUnit; | ||
| import okhttp3.OkHttpClient; | ||
|
|
||
| final class ServerUpdateExample { | ||
|
|
||
| private ServerUpdateExample() {} | ||
|
|
||
| @SuppressWarnings({ | ||
| "PMD.CyclomaticComplexity", | ||
| "PMD.CognitiveComplexity", | ||
| "PMD.NPathComplexity", | ||
| "PMD.NcssCount", | ||
| "PMD.SystemPrintln", | ||
| "PMD.AvoidThrowingRawExceptionTypes", | ||
| "PMD.AvoidDuplicateLiterals" | ||
| }) | ||
| public static void main(String[] args) throws IOException { | ||
| // Credentials are read from the credentialsFile in `~/.stackit/credentials.json` or the env | ||
| // STACKIT_SERVICE_ACCOUNT_KEY_PATH / STACKIT_SERVICE_ACCOUNT_KEY | ||
| CoreConfiguration configuration = new CoreConfiguration(); | ||
|
|
||
| OkHttpClient httpClient = new OkHttpClient(); | ||
| KeyFlowAuthenticator authenticator = new KeyFlowAuthenticator(httpClient, configuration); | ||
| httpClient = | ||
| httpClient | ||
| .newBuilder() | ||
| .authenticator(authenticator) | ||
| // Some create / update requests may take a few seconds. | ||
| // To prevent a timeout, we increase the read timeout to 30 seconds | ||
| .readTimeout(Duration.ofSeconds(30)) | ||
| .build(); | ||
|
|
||
| ServerUpdateApi serverUpdateApi = new ServerUpdateApi(httpClient, configuration); | ||
|
|
||
| // the id of your STACKIT project, read from env var for this example | ||
| String projectId = System.getenv("STACKIT_PROJECT_ID"); | ||
| if (projectId == null || projectId.isEmpty()) { | ||
| System.err.println("Environment variable 'STACKIT_PROJECT_ID' not found."); | ||
| return; | ||
| } | ||
|
|
||
| // the region which should be used to interact with serverupdate | ||
| String region = "eu01"; // NOPMD | ||
|
|
||
| // the id of your STACKIT server, read from env var for this example | ||
| String serverId = System.getenv("STACKIT_SERVER_ID"); | ||
| if (serverId == null || serverId.isEmpty()) { | ||
| System.err.println("Environment variable 'STACKIT_SERVER_ID' not found."); | ||
| return; | ||
| } | ||
|
|
||
| try { | ||
| /* | ||
| * /////////////////////////////////////////////////////// | ||
| * // U P D A T E P O L I C I E S // | ||
| * /////////////////////////////////////////////////////// | ||
| */ | ||
| /* fetching all available update policies */ | ||
| System.out.println("List all available update policies:"); | ||
| GetUpdatePoliciesResponse listUpdatePolicies = | ||
| serverUpdateApi.listUpdatePolicies(projectId); | ||
| Objects.requireNonNull(listUpdatePolicies.getItems()); | ||
| for (UpdatePolicy policy : listUpdatePolicies.getItems()) { | ||
| System.out.println("*************************"); | ||
| System.out.println("* Policy name: " + policy.getName()); | ||
| System.out.println("* Description: " + policy.getDescription()); | ||
| System.out.println("* Policy ID: " + policy.getId()); | ||
| System.out.println("* RRULE: " + policy.getRrule()); | ||
| System.out.println("* Enabled: " + policy.getEnabled()); | ||
| System.out.println("* Default: " + policy.getDefault()); | ||
| } | ||
|
|
||
| /* | ||
| * /////////////////////////////////////////////////////// | ||
| * // U P D A T E E N A B L E M E N T // | ||
| * /////////////////////////////////////////////////////// | ||
| */ | ||
| /* checking if update service is enabled for the server */ | ||
| System.out.println("\nChecking update service status for the server:"); | ||
| try { | ||
| GetUpdateServiceResponse updateServiceStatus = | ||
| serverUpdateApi.getServiceResource(projectId, serverId, region); | ||
| assert updateServiceStatus.getEnabled() != null; | ||
| System.out.println("* Update service enabled: " + updateServiceStatus.getEnabled()); | ||
| } catch (ApiException e) { | ||
| // If response status is not found, update service is not enabled for the server | ||
| if (e.getCode() == HttpURLConnection.HTTP_NOT_FOUND) { | ||
| System.out.println("* Update service is not enabled for the server"); | ||
| System.out.println("* Enabling update service..."); | ||
| String policyIdString = listUpdatePolicies.getItems().get(0).getId(); | ||
| assert policyIdString != null; | ||
marceljk marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| UUID policyId = UUID.fromString(policyIdString); | ||
| serverUpdateApi.enableServiceResource( | ||
| projectId, | ||
| serverId, | ||
| region, | ||
| new EnableServiceResourcePayload().updatePolicyId(policyId)); | ||
| System.out.println("* Update service successful enabled for the server"); | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * /////////////////////////////////////////////////////// | ||
| * // U P D A T E S C H E D U L E // | ||
| * /////////////////////////////////////////////////////// | ||
| */ | ||
| /* creating a new nightly update schedule for the server*/ | ||
| System.out.println("\nCreating a new update schedule:"); | ||
| UpdateSchedule newSchedule = | ||
| serverUpdateApi.createUpdateSchedule( | ||
| projectId, | ||
| serverId, | ||
| region, | ||
| new CreateUpdateSchedulePayload() | ||
| .name("Nightly 3 AM") | ||
| .enabled(true) | ||
| .maintenanceWindow(5) | ||
| .rrule( | ||
| "DTSTART;TZID=Europe/Berlin:20251210T030000 RRULE:FREQ=DAILY;INTERVAL=1")); | ||
| System.out.println("* Schedule ID: " + newSchedule.getId()); | ||
| System.out.println("* Name: " + newSchedule.getName()); | ||
| System.out.println("* Enabled: " + newSchedule.getEnabled()); | ||
| System.out.println("* RRULE: " + newSchedule.getRrule()); | ||
| System.out.println("* Maintenance Window: " + newSchedule.getMaintenanceWindow()); | ||
|
|
||
| /* updating the created update schedule */ | ||
| System.out.println("\nUpdating the update schedule:"); | ||
| UpdateSchedule updatedSchedule = | ||
| serverUpdateApi.updateUpdateSchedule( | ||
| projectId, | ||
| serverId, | ||
| newSchedule.getId().toString(), | ||
| region, | ||
| new UpdateUpdateSchedulePayload() | ||
| .name("Nightly 10 PM") | ||
| .enabled(false) | ||
| .maintenanceWindow(2) | ||
| .rrule( | ||
| "DTSTART;TZID=Europe/Berlin:20251210T220000 RRULE:FREQ=DAILY;INTERVAL=1")); | ||
| System.out.println("* Schedule ID: " + updatedSchedule.getId()); | ||
| System.out.println("* Name: " + updatedSchedule.getName()); | ||
| System.out.println("* Enabled: " + updatedSchedule.getEnabled()); | ||
| System.out.println("* RRULE: " + updatedSchedule.getRrule()); | ||
| System.out.println("* Maintenance Window: " + updatedSchedule.getMaintenanceWindow()); | ||
|
|
||
| /* list all available update schedules of the server */ | ||
| System.out.println("\nList all update schedules"); | ||
| GetUpdateSchedulesResponse listUpdateSchedules = | ||
| serverUpdateApi.listUpdateSchedules(projectId, serverId, region); | ||
| assert listUpdateSchedules.getItems() != null; | ||
marceljk marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| for (UpdateSchedule schedule : listUpdateSchedules.getItems()) { | ||
| System.out.println("*************************"); | ||
| System.out.println("* Schedule ID: " + schedule.getId()); | ||
| System.out.println("* Name: " + schedule.getName()); | ||
| System.out.println("* Enabled: " + schedule.getEnabled()); | ||
| System.out.println("* RRULE: " + schedule.getRrule()); | ||
| System.out.println("* Maintenance Window: " + schedule.getMaintenanceWindow()); | ||
| } | ||
|
|
||
| /* deleting the update schedule we created */ | ||
| System.out.println("\nDeleting update schedule:"); | ||
| serverUpdateApi.deleteUpdateSchedule( | ||
| projectId, serverId, newSchedule.getId().toString(), region); | ||
| System.out.println("* Deleted update schedule successful"); | ||
|
|
||
| /* | ||
| * /////////////////////////////////////////////////////// | ||
| * // U P D A T E S // | ||
| * /////////////////////////////////////////////////////// | ||
| */ | ||
| /* trigger manually an update of the server */ | ||
| System.out.println("\nTrigger a server update:"); | ||
| Update newUpdate = | ||
| serverUpdateApi.createUpdate( | ||
| projectId, | ||
| serverId, | ||
| region, | ||
| new CreateUpdatePayload() | ||
| .backupBeforeUpdate(false) | ||
| .maintenanceWindow(11)); | ||
| System.out.println("* Update status: " + newUpdate.getStatus()); | ||
|
|
||
| /* wait for the update to complete */ | ||
| while (Objects.equals( | ||
| serverUpdateApi | ||
| .getUpdate(projectId, serverId, newUpdate.getId().toString(), region) | ||
| .getStatus(), | ||
| "running")) { | ||
| System.out.println("Waiting for update to complete ..."); | ||
| TimeUnit.SECONDS.sleep(5); | ||
| } | ||
| System.out.println("* Update finished"); | ||
|
|
||
| /* fetch details of the update */ | ||
| System.out.println("\nUpdate details:"); | ||
| Update getUpdate = | ||
| serverUpdateApi.getUpdate( | ||
| projectId, serverId, newUpdate.getId().toString(), region); | ||
| System.out.println("* ID: " + getUpdate.getId()); | ||
| System.out.println("* Status: " + getUpdate.getStatus()); | ||
| System.out.println("* Installed updates: " + getUpdate.getInstalledUpdates()); | ||
| System.out.println("* Failed updates: " + getUpdate.getFailedUpdates()); | ||
| if (getUpdate.getFailReason() != null && !getUpdate.getFailReason().isEmpty()) { | ||
| System.out.println("* Fail reason: " + getUpdate.getFailReason()); | ||
| } | ||
| System.out.println("* Start date: " + getUpdate.getStartDate()); | ||
| System.out.println("* End date: " + getUpdate.getEndDate()); | ||
|
|
||
| /* list all executed updated */ | ||
| System.out.println("\nList updates:"); | ||
| GetUpdatesListResponse listUpdates = | ||
| serverUpdateApi.listUpdates(projectId, serverId, region); | ||
| assert listUpdates.getItems() != null; | ||
marceljk marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| for (Update update : listUpdates.getItems()) { | ||
| System.out.println("*************************"); | ||
| System.out.println("* ID: " + update.getId()); | ||
| System.out.println("* Status: " + update.getStatus()); | ||
| System.out.println("* Installed updates: " + update.getInstalledUpdates()); | ||
| System.out.println("* Failed updates: " + update.getFailedUpdates()); | ||
| if (update.getFailReason() != null && !update.getFailReason().isEmpty()) { | ||
| System.out.println("* Fail reason: " + update.getFailReason()); | ||
| } | ||
| System.out.println("* Start date: " + update.getStartDate()); | ||
| System.out.println("* End date: " + update.getEndDate()); | ||
| } | ||
| } catch (ApiException | InterruptedException e) { | ||
| throw new RuntimeException(e); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| ## v0.1.0 | ||
| - Initial onboarding of STACKIT Java SDK for Server Update service |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| # STACKIT Java SDK for STACKIT Server Update Management API | ||
|
|
||
| - API version: 2.0 | ||
|
|
||
| API endpoints for Server Update Operations on STACKIT Servers. | ||
|
|
||
|
|
||
| This package is part of the STACKIT Java SDK. For additional information, please visit the [GitHub repository](https://github.com/stackitcloud/stackit-sdk-java) of the SDK. | ||
|
|
||
| ## Installation from Maven Central (recommended) | ||
|
|
||
| The release artifacts for this SDK submodule are available on [Maven Central](https://central.sonatype.com/artifact/cloud.stackit.sdk/serverupdate). | ||
|
|
||
| ### Maven users | ||
|
|
||
| Add this dependency to your project's POM: | ||
|
|
||
| ```xml | ||
| <dependency> | ||
| <groupId>cloud.stackit.sdk</groupId> | ||
| <artifactId>serverupdate</artifactId> | ||
| <version><SDK_VERSION></version> | ||
| <scope>compile</scope> | ||
| </dependency> | ||
| ``` | ||
|
|
||
| ### Gradle users | ||
|
|
||
| Add this dependency to your project's build file: | ||
|
|
||
| ```groovy | ||
| repositories { | ||
| mavenCentral() | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation "cloud.stackit.sdk:serverupdate:<SDK_VERSION>" | ||
| } | ||
| ``` | ||
|
|
||
| ## Installation from local build | ||
|
|
||
| Building the API client library requires: | ||
| 1. Java SDK (version 11 to 21 should be supported) installed on your system | ||
|
|
||
| To install the API client library to your local Maven repository, simply execute: | ||
|
|
||
| ```shell | ||
| ./gradlew services:serverupdate:publishToMavenLocal | ||
| ``` | ||
|
|
||
| ### Maven users | ||
|
|
||
| Add this dependency to your project's POM: | ||
|
|
||
| ```xml | ||
| <dependency> | ||
| <groupId>cloud.stackit.sdk</groupId> | ||
| <artifactId>serverupdate</artifactId> | ||
| <version><SDK_VERSION></version> | ||
| <scope>compile</scope> | ||
| </dependency> | ||
| ``` | ||
|
|
||
| ### Gradle users | ||
|
|
||
| Add this dependency to your project's build file: | ||
|
|
||
| ```groovy | ||
| repositories { | ||
| mavenLocal() | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation "cloud.stackit.sdk:serverupdate:<SDK_VERSION>" | ||
| } | ||
| ``` | ||
|
|
||
| ## Getting Started | ||
|
|
||
| See the [serverupdate examples](https://github.com/stackitcloud/stackit-sdk-java/tree/main/examples/serverupdate/src/main/java/cloud/stackit/sdk/serverupdate/examples). | ||
|
|
||
| ## Recommendation | ||
|
|
||
| It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 0.1.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
|
|
||
| ext { | ||
| jakarta_annotation_version = "1.3.5" | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation "com.google.code.findbugs:jsr305:3.0.2" | ||
| implementation 'com.squareup.okhttp3:okhttp:4.12.0' | ||
| implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0' | ||
| implementation 'com.google.code.gson:gson:2.9.1' | ||
| implementation 'io.gsonfire:gson-fire:1.9.0' | ||
| implementation 'jakarta.ws.rs:jakarta.ws.rs-api:2.1.6' | ||
| implementation 'org.openapitools:jackson-databind-nullable:0.2.6' | ||
| implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0' | ||
| implementation "jakarta.annotation:jakarta.annotation-api:$jakarta_annotation_version" | ||
| testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.3' | ||
| testImplementation 'org.mockito:mockito-core:3.12.4' | ||
| testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.3' | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.