Skip to content
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

Enable publicapi to run on CF #3119

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3852b4b
Updated .gitignore and refactored health check config in metricsforwa…
bonzofenix Aug 7, 2024
a4ff5ec
Add new files for autoscaler API and security, refactor scaling engin…
bonzofenix Aug 7, 2024
fa178f4
Remove scaling engine client and refactor scaling history handler
bonzofenix Aug 7, 2024
758f0fd
Refactor API test suite and update health check configuration
bonzofenix Aug 7, 2024
a45b9c5
Add go:generate directive and remote parsing to ogen, update health p…
bonzofenix Aug 7, 2024
16bbb99
Add Makefile for eventgenerator and refactor eventgenerator tests
bonzofenix Aug 7, 2024
9285c85
Refactor HealthConfig to use BasicAuth model and update HTTP client c…
bonzofenix Aug 7, 2024
aa9a71c
Refactor basic auth configuration in healthendpoint
bonzofenix Aug 7, 2024
2821c00
Refactor health endpoint and update HTTP client creation
bonzofenix Aug 7, 2024
4f8ea86
Add BasicAuthenticationMiddleware for healthcheck endpoint
bonzofenix Aug 7, 2024
204b2dc
Refactor scaling history API and update Makefile for new paths
bonzofenix Aug 7, 2024
31ddfbb
WIP - xfcc middleware for publicapi
bonzofenix Aug 7, 2024
cef43b9
Merge branch 'main' into 754-publicapi-in-cf
bonzofenix Aug 29, 2024
2103d1f
Merge branch 'main' into 754-publicapi-in-cf
bonzofenix Oct 10, 2024
25b355a
Merge debox
bonzofenix Oct 10, 2024
f0bb44a
Remove API credential routes and associated middleware from public AP…
bonzofenix Oct 10, 2024
f385475
Remove unused net/http import and apiHttpClient from api_suite_test i…
bonzofenix Oct 10, 2024
817c1de
Fix lint
bonzofenix Oct 10, 2024
c5f8138
Small fix
bonzofenix Oct 10, 2024
4b10025
Remove Health Port configuration from metricsforwarder tests
bonzofenix Oct 10, 2024
b8bdaed
Fix lint
bonzofenix Oct 10, 2024
288606f
Comment out setupMainRouter functions in eventgenerator and scalingen…
bonzofenix Oct 10, 2024
167ec9c
Fix test
bonzofenix Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ src/acceptance/assets/app/go_app/internal/openapi-specs.bundled
src/acceptance/assets/app/go_app/internal/applicationmetric/oas*gen.go
src/acceptance/assets/app/go_app/internal/custommetrics/oas*gen.go
src/acceptance/assets/app/go_app/internal/policy/oas*gen.go
src/autoscaler/helpers/apis/scalinghistory/oas*gen.go
src/autoscaler/api/apis/scalinghistory/oas*gen.go
src/autoscaler/scalingengine/apis/scalinghistory/oas*gen.go

# Autogenerated files
go.work.sum
Expand Down
213 changes: 213 additions & 0 deletions api/internal-scaling-history-api.openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
openapi: 3.0.0
info:
title: Scaling History API
description: List scaling history of an application
version: 1.0.0
license:
name: "Apache License Version 2.0"
# identifier: "Apache-2.0" # Requires at least OpenAPI 3.1.0
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
tags:
- name: Scaling History API V1
description: List the scaling history of an Application
paths:
/v1/apps/{guid}/scaling_histories:
parameters:
- name: guid
in: path
required: true
description: |
The GUID identifying the application for which the scaling history is fetched.

It can be found in the `application_id` property of the JSON object stored in the
`VCAP_APPLICATION` environment variable.
schema:
$ref: "./shared_definitions.yaml#/schemas/GUID"
- name: start-time
in: query
description: |
The start time in the number of nanoseconds elapsed since January 1, 1970 UTC.
schema:
type: integer
default: 0
example: start-time=1494989539138350432
- name: end-time
in: query
description: |
The end time in the number of nanoseconds elapsed since January 1, 1970 UTC.
schema:
type: integer
default: -1
example: end-time=1494989549117047288
- name: order-direction
in: query
description: |
The sorting order. The scaling history will be order by timestamp ascending or descending.
schema:
type: string
enum: ["asc", "desc"]
default: desc
example: order-direction=desc
- name: order
in: query
description: |
Deprecated: Use order-direction instead.
schema:
type: string
enum: ["asc", "desc"]
deprecated: true
example: order=desc
- name: page
in: query
description: The page number to query
schema:
type: integer
minimum: 1
default: 1
example: page=1
- name: results-per-page
in: query
description: Number of entries shown per page.
schema:
type: integer
minimum: 0
default: 50
example: results-per-page=10
get:
summary: Retrieves the scaling history of an application.
description: |
Use to retrieve scaling history for an app.
tags:
- Scaling History API V1
responses:
"200":
description: "OK"
content:
application/json:
schema:
$ref: "#/components/schemas/History"
default:
$ref: "./shared_definitions.yaml#/responses/Error"
security: []
x-codegen-request-body-name: body
components:
schemas:
History:
description: Object containing scaling history.
type: object
properties:
total_results:
type: integer
format: int64
description: Number of history entries found for the given query.
example: 2
total_pages:
type: integer
format: int64
description: Number of Pages from the query
example: 1
page:
type: integer
format: int64
description: Number of the current page.
example: 1
prev_url:
type: string
format: uri
next_url:
type: string
format: uri
resources:
type: array
items:
$ref: '#/components/schemas/HistoryEntry'
HistoryEntry:
description: "Properties common for each entry in the scaling history."
type: object
oneOf:
- $ref: "#/components/schemas/HistoryErrorEntry"
- $ref: "#/components/schemas/HistoryIgnoreEntry"
- $ref: "#/components/schemas/HistorySuccessEntry"
# Unfortunately, we cannot use a discriminator here, as the property MUST be a string, see also https://github.com/OAI/OpenAPI-Specification/issues/2731
# discriminator:
# propertyName: status
# mapping:
# 0: "#/components/schemas/HistorySuccessEntry"
# 1: "#/components/schemas/HistoryErrorEntry"
# 2: "#/components/schemas/HistoryIgnoreEntry"
properties:
status:
type: integer
format: int64
enum: [0, 1, 2]
description: |
Following stati are possible:
+ 0: The scaling was done successfully.
+ 1: The scaling failed explicitly.
+ 2: The scaling was ignored.
This field is as well a selector of which of the other ones are used and which not.
example: 0
app_id:
$ref: "./shared_definitions.yaml#/schemas/GUID"
timestamp:
type: integer
description: |
The scaling time in the number of nanoseconds elapsed since January 1, 1970 UTC.
example: 1494989539138350432
scaling_type:
type: integer
format: int64
enum: [0, 1]
description: |
There are two different scaling types:
+ 0: This represents `ScalingTypeDynamic`. The scaling has been done due to a dynamic
scaling rule, reacting on metrics provided by the app.
+ 1: This represents `ScalingTypeSchedule`. The scaling has been done due to a
scheduled period changing the default instance limits.
example: 0
old_instances:
type: integer
format: int64
minimum: -1
description: The number of instances before the scaling. -1 means that the value is not applicable.
example: 1
new_instances:
type: integer
format: int64
minimum: -1
description: The number of instances after the scaling. -1 means that the value is not applicable.
example: 2
reason:
type: string
description: Textual information about what triggered the scaling event.
example: -1 instance(s) because cpu < 20% for 60 seconds
message:
type: string
description: Textual information about the scaling event.
example: app
HistoryErrorEntry:
description: Description of a failed scaling even in history.
type: object
properties:
error:
type: string
description: |
In case the scaling failed, the reason is provided in this field.
example: failed to compute new app instances
HistoryIgnoreEntry:
description: Description of an ignored scaling event in history.
type: object
properties:
ignore_reason:
type: string
description: |
In case the scaling was ignored, the reason is provided in this field.
example: app in cooldown period
HistorySuccessEntry:
description: Description of a successful scaling event event in history.
type: object
properties: {} # No extra fields needed in this variant.
securitySchemes:
basicAuth:
type: http
scheme: basic
22 changes: 14 additions & 8 deletions src/autoscaler/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,24 @@ GINKGO_VERSION = v$(shell cat ../../.tool-versions | grep ginkgo | cut --delimi


# ogen generated OpenAPI clients and servers
openapi-generated-clients-and-servers-dir := ./helpers/apis/scalinghistory
openapi-generated-clients-and-servers-api-dir := ./api/apis/scalinghistory
openapi-generated-clients-and-servers-scalingengine-dir := ./scalingengine/apis/scalinghistory

openapi-spec-path := ../../api
openapi-specs-list = $(wildcard ${openapi-spec-path}/*.yaml)

openapi-generated-clients-and-servers-files = $(wildcard ${openapi-generated-clients-and-servers-dir}/*.go)
openapi-generated-clients-and-servers-api-files = $(wildcard ${openapi-generated-clients-and-servers-api-dir}/*.go)
openapi-generated-clients-and-servers-scalingengine-files = $(wildcard ${openapi-generated-clients-and-servers-scalingengine-dir}/*.go)


.PHONY: generate-openapi-generated-clients-and-servers
generate-openapi-generated-clients-and-servers: ${openapi-generated-clients-and-servers-dir} ${openapi-generated-clients-and-servers-files}
${openapi-generated-clients-and-servers-dir} ${openapi-generated-clients-and-servers-files} &: $(wildcard ./helpers/apis/generate.go) ${openapi-specs-list} ./go.mod ./go.sum
generate-openapi-generated-clients-and-servers: ${openapi-generated-clients-and-servers-api-dir} ${openapi-generated-clients-and-servers-api-files} ${openapi-generated-clients-and-servers-scalingengine-dir} ${openapi-generated-clients-and-servers-scalingengine-files}
${openapi-generated-clients-and-servers-api-dir} ${openapi-generated-clients-and-servers-api-files} ${openapi-generated-clients-and-servers-scalingengine-dir} ${openapi-generated-clients-and-servers-scalingengine-files} &: $(wildcard ./scalingengine/apis/generate.go) $(wildcard ./api/apis/generate.go) ${openapi-specs-list} ./go.mod ./go.sum
@echo "# Generating OpenAPI clients and servers"
# $(wildcard ./helpers/apis/generate.go) causes the target to always being executed, no matter if file exists or not.
# $(wildcard ./api/apis/generate.go) causes the target to always being executed, no matter if file exists or not.
# so let's don't fail if file can't be found, e.g. the eventgenerator bosh package does not contain it.
go generate ./helpers/apis/generate.go || true
go generate ./api/apis/generate.go || true
go generate ./scalingengine/apis/generate.go || true

# The presence of the subsequent directory indicates whether the fakes still need to be generated
# or not.
Expand Down Expand Up @@ -91,7 +96,7 @@ build-cf-%:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $*/$* $*/cmd/$*/main.go

# CGO_ENABLED := 1 is required to enforce dynamic linking which is a requirement of dynatrace.
build-%: ${openapi-generated-clients-and-servers-dir} ${openapi-generated-clients-and-servers-files}
build-%: ${openapi-generated-clients-and-servers-api-dir} ${openapi-generated-clients-and-servers-api-files} ${openapi-generated-clients-and-servers-scalingengine-dir} ${openapi-generated-clients-and-servers-scalingengine-files}
@echo "# building $*"
@CGO_ENABLED=1 go build $(BUILDTAGS) $(BUILDFLAGS) -o build/$* $*/cmd/$*/main.go

Expand Down Expand Up @@ -145,4 +150,5 @@ clean:
@rm --force --recursive 'build'
@rm --force --recursive 'fakes'
@rm --force --recursive 'vendor'
@rm --force --recursive "${openapi-generated-clients-and-servers-dir}"
@rm --force --recursive "${openapi-generated-clients-and-servers-api-dir}"
@rm --force --recursive "${openapi-generated-clients-and-servers-scalingengine-dir}"
3 changes: 3 additions & 0 deletions src/autoscaler/api/apis/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package apis

//go:generate go run github.com/ogen-go/ogen/cmd/ogen --config ogen-config.yaml --package scalinghistory --target scalinghistory --clean ../../../../api/scaling-history-api.openapi.yaml
2 changes: 2 additions & 0 deletions src/autoscaler/api/apis/ogen-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
parser:
allow_remote: true
41 changes: 19 additions & 22 deletions src/autoscaler/api/cmd/api/api_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import (

"code.cloudfoundry.org/app-autoscaler/src/autoscaler/cf/mocks"
"code.cloudfoundry.org/app-autoscaler/src/autoscaler/helpers"

. "code.cloudfoundry.org/app-autoscaler/src/autoscaler/testhelpers"
"code.cloudfoundry.org/app-autoscaler/src/autoscaler/testhelpers"

"code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/config"
"code.cloudfoundry.org/app-autoscaler/src/autoscaler/db"
Expand All @@ -37,18 +36,17 @@ const (
)

var (
apPath string
cfg config.Config
configFile *os.File
apiHttpClient *http.Client
healthHttpClient *http.Client
catalogBytes string
schedulerServer *ghttp.Server
brokerPort int
publicApiPort int
healthport int
infoBytes string
ccServer *mocks.Server
apPath string
cfg config.Config
configFile *os.File
apiHttpClient *http.Client
bonzofenix marked this conversation as resolved.
Show resolved Hide resolved
schedulerServer *ghttp.Server
catalogBytes string
brokerPort int
publicApiPort int
healthport int
infoBytes string
ccServer *mocks.Server
)

func TestApi(t *testing.T) {
Expand All @@ -64,7 +62,7 @@ type testdata struct {

var _ = SynchronizedBeforeSuite(func() []byte {
info := testdata{}
dbUrl := GetDbUrl()
dbUrl := testhelpers.GetDbUrl()

database, e := db.GetConnection(dbUrl)
if e != nil {
Expand Down Expand Up @@ -135,7 +133,7 @@ var _ = SynchronizedBeforeSuite(func() []byte {
}
cfg.Logging.Level = "info"
cfg.DB = make(map[string]db.DatabaseConfig)
dbUrl := GetDbUrl()
dbUrl := testhelpers.GetDbUrl()
cfg.DB[db.BindingDb] = db.DatabaseConfig{
URL: dbUrl,
MaxOpenConnections: 10,
Expand Down Expand Up @@ -201,8 +199,10 @@ var _ = SynchronizedBeforeSuite(func() []byte {
ServerConfig: helpers.ServerConfig{
Port: healthport,
},
HealthCheckUsername: "healthcheckuser",
HealthCheckPassword: "healthcheckpassword",
BasicAuth: models.BasicAuth{
Username: "healthcheckuser",
Password: "healthcheckpassword",
},
}
cfg.RateLimit.MaxAmount = 10
cfg.RateLimit.ValidDuration = 1 * time.Second
Expand All @@ -211,9 +211,6 @@ var _ = SynchronizedBeforeSuite(func() []byte {

configFile = writeConfig(&cfg)

apiHttpClient = NewApiClient()

healthHttpClient = &http.Client{}
})

var _ = SynchronizedAfterSuite(func() {
Expand Down Expand Up @@ -281,6 +278,6 @@ func (ap *ApiRunner) Interrupt() {

func readFile(filename string) string {
contents, err := os.ReadFile(filename)
FailOnError("Failed to read file:"+filename+" ", err)
testhelpers.FailOnError("Failed to read file:"+filename+" ", err)
return string(contents)
}
Loading
Loading