From 59946d1799b8c561a91f2722a9d43c5ecd85827c Mon Sep 17 00:00:00 2001 From: Carlo Goetz Date: Tue, 9 Dec 2025 12:11:18 +0100 Subject: [PATCH 1/8] feat(logs) add example for logs API --- examples/logs/go.mod | 13 ++++++ examples/logs/go.sum | 10 +++++ examples/logs/logs.go | 102 ++++++++++++++++++++++++++++++++++++++++++ go.work | 1 + 4 files changed, 126 insertions(+) create mode 100644 examples/logs/go.mod create mode 100644 examples/logs/go.sum create mode 100644 examples/logs/logs.go diff --git a/examples/logs/go.mod b/examples/logs/go.mod new file mode 100644 index 000000000..e551bf146 --- /dev/null +++ b/examples/logs/go.mod @@ -0,0 +1,13 @@ +module github.com/stackitcloud/stackit-sdk-go/examples/logs + +go 1.21 + +require ( + github.com/stackitcloud/stackit-sdk-go/core v0.20.1 + github.com/stackitcloud/stackit-sdk-go/services/logs v0.1.0 +) + +require ( + github.com/golang-jwt/jwt/v5 v5.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect +) diff --git a/examples/logs/go.sum b/examples/logs/go.sum new file mode 100644 index 000000000..a89c3d692 --- /dev/null +++ b/examples/logs/go.sum @@ -0,0 +1,10 @@ +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/stackitcloud/stackit-sdk-go/core v0.20.1 h1:odiuhhRXmxvEvnVTeZSN9u98edvw2Cd3DcnkepncP3M= +github.com/stackitcloud/stackit-sdk-go/core v0.20.1/go.mod h1:fqto7M82ynGhEnpZU6VkQKYWYoFG5goC076JWXTUPRQ= +github.com/stackitcloud/stackit-sdk-go/services/logs v0.1.0 h1:Fck91pz2Oxk8dUd2lOdnsIMWSCzBzAHJp7ivqAJ59is= +github.com/stackitcloud/stackit-sdk-go/services/logs v0.1.0/go.mod h1:VM+++rhzI2/lvhyGKg0FCiEfnrADWykcdHLbECrl6T0= diff --git a/examples/logs/logs.go b/examples/logs/logs.go new file mode 100644 index 000000000..25cdea8a5 --- /dev/null +++ b/examples/logs/logs.go @@ -0,0 +1,102 @@ +package main + +import ( + "context" + "log" + + "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/utils" + "github.com/stackitcloud/stackit-sdk-go/services/logs" +) + +func main() { + ctx := context.Background() + + projectId := "PROJECT_ID" // the uuid of your STACKIT project + regionId := "eu01" + + client, err := logs.NewAPIClient( + config.WithRegion(regionId), + ) + if err != nil { + log.Fatalf("[Logs API] Creating API client: %v\n", err) + } + + // Create a Logs Instance + var createdInstance string + createInstancePayload := logs.CreateLogsInstancePayload{ + DisplayName: utils.Ptr("my-logs-instance"), + RetentionDays: utils.Ptr(int64(1)), + } + createResp, err := client.CreateLogsInstance(ctx, projectId, regionId). + CreateLogsInstancePayload(createInstancePayload). + Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `CreateLogsInstance`: %v\n", err) + } + createdInstance = *createResp.Id + log.Printf("[Logs API] Created Logs Instance with ID \"%s\".\n", createdInstance) + + // List Logs Instances + listResp, err := client.ListLogsInstances(ctx, projectId, regionId).Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `ListLogsInstances`: %v\n", err) + } + log.Printf("[Logs API] Retrieved %d Logs Instances.\n", len(*listResp.Instances)) + + // Get the created Logs Instance + getResp, err := client.GetLogsInstance(ctx, projectId, regionId, createdInstance).Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `GetLogsInstance`: %v\n", err) + } + log.Printf("[Logs API] Retrieved Logs Instance with ID \"%s\" and Display Name \"%s\".\n", *getResp.Id, *getResp.DisplayName) + + // Update the created Logs Instance + updatePayload := logs.UpdateLogsInstancePayload{ + DisplayName: utils.Ptr("my-updated-logs-instance"), + RetentionDays: utils.Ptr(int64(7)), + } + updateResp, err := client.UpdateLogsInstance(ctx, projectId, regionId, createdInstance). + UpdateLogsInstancePayload(updatePayload). + Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `UpdateLogsInstance`: %v\n", err) + } + log.Printf("[Logs API] Updated Logs Instance with ID \"%s\" to Display Name \"%s\".\n", *updateResp.Id, *updateResp.DisplayName) + + // Create an Access Token + createTokenPayload := logs.CreateAccessTokenPayload{ + DisplayName: utils.Ptr("my-access-token"), + Permissions: &[]string{"read"}, + } + createTokenResp, err := client.CreateAccessToken(ctx, projectId, regionId, createdInstance). + CreateAccessTokenPayload(createTokenPayload). + Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `CreateAccessToken`: %v\n", err) + } + log.Printf("[Logs API] Created Access Token with ID \"%s\".\n", *createTokenResp.Id) + + // Add Access Token to Logs Instance + err = client.UpdateAccessToken(ctx, projectId, regionId, createdInstance, *createTokenResp.Id). + // needs at least an empty payload + UpdateAccessTokenPayload(logs.UpdateAccessTokenPayload{}). + Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `UpdateAccessToken`: %v\n", err) + } + + // Delete all Access Tokens from Logs Instance + tokenList, err := client.DeleteAllAccessTokens(ctx, projectId, regionId, createdInstance).Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `DeleteAllAccessTokens`: %v\n", err) + } + log.Printf("[Logs API] Deleted %d Access Tokens from Logs Instance with ID \"%s\".\n", len(*tokenList.Tokens), createdInstance) + + // Delete the created Logs Instance + err = client.DeleteLogsInstance(ctx, projectId, regionId, createdInstance).Execute() + if err != nil { + log.Fatalf("[Logs API] Error when calling `DeleteLogsInstance`: %v\n", err) + } + log.Printf("[Logs API] Deleted Logs Instance with ID \"%s\".\n", createdInstance) +} diff --git a/go.work b/go.work index 860a2a575..f661cc459 100644 --- a/go.work +++ b/go.work @@ -14,6 +14,7 @@ use ( ./examples/kms ./examples/loadbalancer ./examples/logme + ./examples/logs ./examples/mariadb ./examples/middleware ./examples/mongodbflex From ec089535ccb35fcd48a75d606d22905373d83866 Mon Sep 17 00:00:00 2001 From: Carlo Goetz Date: Thu, 11 Dec 2025 17:49:26 +0100 Subject: [PATCH 2/8] feat(logs) add waiters for logs API --- services/logs/go.mod | 1 + services/logs/wait/wait.go | 57 +++++++++++ services/logs/wait/wait_test.go | 168 ++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 services/logs/wait/wait.go create mode 100644 services/logs/wait/wait_test.go diff --git a/services/logs/go.mod b/services/logs/go.mod index 453bc6e61..a4ff81ccb 100644 --- a/services/logs/go.mod +++ b/services/logs/go.mod @@ -3,6 +3,7 @@ module github.com/stackitcloud/stackit-sdk-go/services/logs go 1.21 require ( + github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 github.com/stackitcloud/stackit-sdk-go/core v0.20.0 ) diff --git a/services/logs/wait/wait.go b/services/logs/wait/wait.go new file mode 100644 index 000000000..50efa657b --- /dev/null +++ b/services/logs/wait/wait.go @@ -0,0 +1,57 @@ +package wait + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" + "github.com/stackitcloud/stackit-sdk-go/core/wait" + "github.com/stackitcloud/stackit-sdk-go/services/logs" +) + +type APIClientInterface interface { + GetLogsInstanceExecute(ctx context.Context, projectId string, regionId string, instanceId string) (*logs.LogsInstance, error) +} + +func CreateLogsInstanceWaitHandler(ctx context.Context, client APIClientInterface, projectID, region, instanceID string) *wait.AsyncActionHandler[logs.LogsInstance] { + handler := wait.New(func() (waitFinished bool, response *logs.LogsInstance, err error) { + instance, err := client.GetLogsInstanceExecute(ctx, projectID, region, instanceID) + if err != nil { + return false, nil, err + } + if instance.Id == nil || instance.Status == nil { + return false, nil, fmt.Errorf("get instance, project: %q, region: %q, instanceID: %q: missing id or status", projectID, region, instanceID) + } + if *instance.Id == instanceID && *instance.Status == logs.LOGSINSTANCESTATUS_ACTIVE { + return true, instance, nil + } + if *instance.Status == logs.LOGSINSTANCESTATUS_DELETING { + return true, nil, fmt.Errorf("creating log instance failed, instance is being deleted") + } + return false, nil, nil + }) + handler.SetTimeout(10 * time.Minute) + return handler +} + +func DeleteLogsInstanceWaitHandler(ctx context.Context, client APIClientInterface, projectID, region, instanceID string) *wait.AsyncActionHandler[logs.LogsInstance] { + handler := wait.New(func() (waitFinished bool, response *logs.LogsInstance, err error) { + _, err = client.GetLogsInstanceExecute(ctx, projectID, region, instanceID) + // the instances is still gettable, e.g. not deleted, when the errors is null + if err == nil { + return false, nil, nil + } + var oapiError *oapierror.GenericOpenAPIError + if errors.As(err, &oapiError) { + if statusCode := oapiError.StatusCode; statusCode == http.StatusNotFound { + return true, nil, nil + } + } + return false, nil, err + }) + handler.SetTimeout(10 * time.Minute) + return handler +} diff --git a/services/logs/wait/wait_test.go b/services/logs/wait/wait_test.go new file mode 100644 index 000000000..9c64aa421 --- /dev/null +++ b/services/logs/wait/wait_test.go @@ -0,0 +1,168 @@ +package wait + +import ( + "context" + "net/http" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" + "github.com/stackitcloud/stackit-sdk-go/core/utils" + "github.com/stackitcloud/stackit-sdk-go/services/logs" +) + +type apiClientMock struct { + getFails bool + returnInstance bool + statusCode int + getLogsResponse *logs.LogsInstance +} + +func (a *apiClientMock) GetLogsInstanceExecute(_ context.Context, _, _, _ string) (*logs.LogsInstance, error) { + if a.getFails { + return nil, &oapierror.GenericOpenAPIError{ + StatusCode: a.statusCode, + } + } + if !a.returnInstance { + return nil, nil + } + return a.getLogsResponse, nil +} + +var PROJECT_ID = uuid.NewString() +var INSTANCE_ID = uuid.NewString() +var REGION = "eu01" + +func TestCreateLogsInstanceWaitHandler(t *testing.T) { + tests := []struct { + description string + getFails bool + wantErr bool + wantResp bool + returnInstance bool + getLogsResponse *logs.LogsInstance + }{ + { + description: "create succeeded", + getFails: false, + wantErr: false, + wantResp: true, + returnInstance: true, + getLogsResponse: &logs.LogsInstance{ + Id: utils.Ptr(INSTANCE_ID), + Status: utils.Ptr(logs.LOGSINSTANCESTATUS_ACTIVE), + }, + }, + { + description: "create failed with error", + getFails: true, + wantErr: true, + wantResp: false, + returnInstance: true, + getLogsResponse: &logs.LogsInstance{ + Id: utils.Ptr(INSTANCE_ID), + Status: utils.Ptr(logs.LOGSINSTANCESTATUS_ACTIVE), + }, + }, + { + description: "create without id", + getFails: false, + wantErr: true, + wantResp: false, + returnInstance: true, + getLogsResponse: &logs.LogsInstance{ + Status: utils.Ptr(logs.LOGSINSTANCESTATUS_ACTIVE), + }, + }, + { + description: "create without status", + getFails: false, + wantErr: true, + wantResp: false, + returnInstance: true, + getLogsResponse: &logs.LogsInstance{ + Id: utils.Ptr(INSTANCE_ID), + }, + }, + { + description: "instance deleting", + getFails: false, + wantErr: true, + wantResp: false, + returnInstance: true, + getLogsResponse: &logs.LogsInstance{ + Id: utils.Ptr(INSTANCE_ID), + Status: utils.Ptr(logs.LOGSINSTANCESTATUS_DELETING), + }, + }, + } + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + client := &apiClientMock{ + getFails: tt.getFails, + getLogsResponse: tt.getLogsResponse, + returnInstance: tt.returnInstance, + } + var instanceWanted *logs.LogsInstance + if tt.wantResp { + instanceWanted = tt.getLogsResponse + } + + handler := CreateLogsInstanceWaitHandler(context.Background(), client, PROJECT_ID, REGION, INSTANCE_ID) + + response, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + if !cmp.Equal(response, instanceWanted) { + t.Fatalf("handler gotRes = %v, want %v", response, instanceWanted) + } + }) + } +} + +func TestDeleteLogsInstanceWaitHandler(t *testing.T) { + tests := []struct { + description string + getFails bool + wantErr bool + statusCode int + }{ + { + description: "delete succeeded", + getFails: true, + statusCode: http.StatusNotFound, + }, + { + description: "delete failed with error", + getFails: true, + wantErr: true, + statusCode: http.StatusInternalServerError, + }, + { + description: "delete still in progress", + getFails: false, + wantErr: true, + statusCode: http.StatusOK, + }, + } + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + client := &apiClientMock{ + getFails: tt.getFails, + returnInstance: false, + statusCode: tt.statusCode, + getLogsResponse: nil, + } + handler := DeleteLogsInstanceWaitHandler(context.Background(), client, PROJECT_ID, REGION, INSTANCE_ID) + _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} From f99b57be3e624cd29010d18c34a374453c9cee24 Mon Sep 17 00:00:00 2001 From: cgoetz-inovex Date: Fri, 12 Dec 2025 13:34:11 +0100 Subject: [PATCH 3/8] Update services/logs/wait/wait_test.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- services/logs/wait/wait_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/logs/wait/wait_test.go b/services/logs/wait/wait_test.go index 9c64aa421..92ad4f763 100644 --- a/services/logs/wait/wait_test.go +++ b/services/logs/wait/wait_test.go @@ -32,7 +32,7 @@ func (a *apiClientMock) GetLogsInstanceExecute(_ context.Context, _, _, _ string return a.getLogsResponse, nil } -var PROJECT_ID = uuid.NewString() +var projectId = uuid.NewString() var INSTANCE_ID = uuid.NewString() var REGION = "eu01" From 6dcd541c968634590b1d4d0dbb1d9a5ceaed0513 Mon Sep 17 00:00:00 2001 From: cgoetz-inovex Date: Fri, 12 Dec 2025 13:34:20 +0100 Subject: [PATCH 4/8] Update services/logs/wait/wait_test.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- services/logs/wait/wait_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/logs/wait/wait_test.go b/services/logs/wait/wait_test.go index 92ad4f763..1e42dc6a5 100644 --- a/services/logs/wait/wait_test.go +++ b/services/logs/wait/wait_test.go @@ -33,7 +33,7 @@ func (a *apiClientMock) GetLogsInstanceExecute(_ context.Context, _, _, _ string } var projectId = uuid.NewString() -var INSTANCE_ID = uuid.NewString() +var instanceId = uuid.NewString() var REGION = "eu01" func TestCreateLogsInstanceWaitHandler(t *testing.T) { From e1685f6afbe4ac53d2b09bb4c4856995e0ca777b Mon Sep 17 00:00:00 2001 From: cgoetz-inovex Date: Fri, 12 Dec 2025 13:34:25 +0100 Subject: [PATCH 5/8] Update services/logs/wait/wait_test.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ruben Hönle --- services/logs/wait/wait_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/logs/wait/wait_test.go b/services/logs/wait/wait_test.go index 1e42dc6a5..1734c58d7 100644 --- a/services/logs/wait/wait_test.go +++ b/services/logs/wait/wait_test.go @@ -34,7 +34,7 @@ func (a *apiClientMock) GetLogsInstanceExecute(_ context.Context, _, _, _ string var projectId = uuid.NewString() var instanceId = uuid.NewString() -var REGION = "eu01" +const region = "eu01" func TestCreateLogsInstanceWaitHandler(t *testing.T) { tests := []struct { From 60daf3af5ff4c2afaa488317da86bb77e0fc828c Mon Sep 17 00:00:00 2001 From: Carlo Goetz Date: Fri, 12 Dec 2025 15:16:45 +0100 Subject: [PATCH 6/8] fix(logs) fix invalid refs after rename in GH UI --- services/logs/wait/wait_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/services/logs/wait/wait_test.go b/services/logs/wait/wait_test.go index 1734c58d7..0c9c2cb80 100644 --- a/services/logs/wait/wait_test.go +++ b/services/logs/wait/wait_test.go @@ -34,6 +34,7 @@ func (a *apiClientMock) GetLogsInstanceExecute(_ context.Context, _, _, _ string var projectId = uuid.NewString() var instanceId = uuid.NewString() + const region = "eu01" func TestCreateLogsInstanceWaitHandler(t *testing.T) { @@ -52,7 +53,7 @@ func TestCreateLogsInstanceWaitHandler(t *testing.T) { wantResp: true, returnInstance: true, getLogsResponse: &logs.LogsInstance{ - Id: utils.Ptr(INSTANCE_ID), + Id: utils.Ptr(instanceId), Status: utils.Ptr(logs.LOGSINSTANCESTATUS_ACTIVE), }, }, @@ -63,7 +64,7 @@ func TestCreateLogsInstanceWaitHandler(t *testing.T) { wantResp: false, returnInstance: true, getLogsResponse: &logs.LogsInstance{ - Id: utils.Ptr(INSTANCE_ID), + Id: utils.Ptr(instanceId), Status: utils.Ptr(logs.LOGSINSTANCESTATUS_ACTIVE), }, }, @@ -84,7 +85,7 @@ func TestCreateLogsInstanceWaitHandler(t *testing.T) { wantResp: false, returnInstance: true, getLogsResponse: &logs.LogsInstance{ - Id: utils.Ptr(INSTANCE_ID), + Id: utils.Ptr(instanceId), }, }, { @@ -94,7 +95,7 @@ func TestCreateLogsInstanceWaitHandler(t *testing.T) { wantResp: false, returnInstance: true, getLogsResponse: &logs.LogsInstance{ - Id: utils.Ptr(INSTANCE_ID), + Id: utils.Ptr(instanceId), Status: utils.Ptr(logs.LOGSINSTANCESTATUS_DELETING), }, }, @@ -111,7 +112,7 @@ func TestCreateLogsInstanceWaitHandler(t *testing.T) { instanceWanted = tt.getLogsResponse } - handler := CreateLogsInstanceWaitHandler(context.Background(), client, PROJECT_ID, REGION, INSTANCE_ID) + handler := CreateLogsInstanceWaitHandler(context.Background(), client, projectId, region, instanceId) response, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) @@ -158,7 +159,7 @@ func TestDeleteLogsInstanceWaitHandler(t *testing.T) { statusCode: tt.statusCode, getLogsResponse: nil, } - handler := DeleteLogsInstanceWaitHandler(context.Background(), client, PROJECT_ID, REGION, INSTANCE_ID) + handler := DeleteLogsInstanceWaitHandler(context.Background(), client, projectId, region, instanceId) _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) if (err != nil) != tt.wantErr { t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) From 09cc812994f644deaf50f04d16dba9327a964f5a Mon Sep 17 00:00:00 2001 From: GokceGK Date: Tue, 16 Dec 2025 10:40:30 +0100 Subject: [PATCH 7/8] update changelogs --- CHANGELOG.md | 4 +++- services/logs/CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4f55d78a..d273f2b7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## Release (2025-XX-YY) - `logs`: - - [v0.1.0](services/logs/CHANGELOG.md#v010) + - [v0.2.0](services/logs/CHANGELOG.md#v020) + - **Feature:** Add new wait handlers for instance creation (`CreateLogsInstanceWaitHandler`), and instance deletion (`DeleteLogsInstanceWaitHandler`) + - [v0.1.0](services/logs/CHANGELOG.md#v010) - **New:** API for logs service ## Release (2025-12-05) - `alb`: diff --git a/services/logs/CHANGELOG.md b/services/logs/CHANGELOG.md index 5c9566347..80ba901b0 100644 --- a/services/logs/CHANGELOG.md +++ b/services/logs/CHANGELOG.md @@ -1,2 +1,5 @@ +## v0.2.0 +- **Feature:** Add new wait handlers for instance creation (`CreateLogsInstanceWaitHandler`), and instance deletion (`DeleteLogsInstanceWaitHandler`) + ## v0.1.0 - **New:** API for logs service \ No newline at end of file From 1bf3f01a71e0ba5f6b1b3d0248254a7940dc8223 Mon Sep 17 00:00:00 2001 From: GokceGK Date: Tue, 16 Dec 2025 10:54:06 +0100 Subject: [PATCH 8/8] bump version from 0.2.0 to 0.3.0 --- services/logs/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/logs/VERSION b/services/logs/VERSION index 1474d00f0..268b0334e 100644 --- a/services/logs/VERSION +++ b/services/logs/VERSION @@ -1 +1 @@ -v0.2.0 +v0.3.0