Skip to content

Commit d2edcff

Browse files
committed
chore: moved the builder to the appropriate path
Moved builder to appropriate path and changed tasks. Updated swagger definition
1 parent 2e3c00d commit d2edcff

6 files changed

Lines changed: 128 additions & 74 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Available APIs at the moment:
3636

3737
### Build API
3838

39-
`POST /system/api/build` - Perform the build of a custom image and push it to repository.
39+
`POST /system/api/v1/build` - Perform the build of a custom image and push it to repository.
4040

4141
More informations [Here](docs/DEPLOYER.md)
4242

TaskfileBuilder.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ tasks:
3030
- if test -z "{{.TARGET}}"; then echo "TARGET IS NOT SET" && exit 1; fi
3131
- if test -z "{{.KIND}}"; then echo "KIND IS NOT SET" && exit 1; fi
3232
- |
33-
echo '{"source": "{{.SOURCE}}", "target": "{{.TARGET}}", "kind": "{{.KIND}}", "file": "{{.REQUIREMENTS}}" }' | http POST $ADMIN_API_URL/system/build Content-Type:application/json Authorization:"{{.AUTH}}"
33+
echo '{"source": "{{.SOURCE}}", "target": "{{.TARGET}}", "kind": "{{.KIND}}", "file": "{{.REQUIREMENTS}}" }' | \
34+
curl -X POST $ADMIN_API_URL/api/v1/build -H "Content-Type: application/json" -H "Authorization: {{.AUTH}}" -d @-
3435
- sleep 5
3536
- task: logs
3637
deps:
@@ -64,7 +65,7 @@ tasks:
6465
list-catalogs:
6566
desc: List catalogs in the registry
6667
cmds:
67-
- http -a $REGISTRY_USER:$REGISTRY_PASS GET "${REGISTRY_HOST}/v2/_catalog"
68+
- curl -u $REGISTRY_USER:$REGISTRY_PASS $REGISTRY_HOST/v2/_catalog
6869
silent: false
6970

7071
list-images:
@@ -73,7 +74,7 @@ tasks:
7374
CATALOG: '{{.CATALOG}}'
7475
cmds:
7576
- if test -z "{{.CATALOG}}"; then echo "CATALOG IS NOT SET" && exit 1; fi
76-
- http -a $REGISTRY_USER:$REGISTRY_PASS GET "${REGISTRY_HOST}/v2/{{.CATALOG}}/tags/list"
77+
- curl -u $REGISTRY_USER:$REGISTRY_PASS $REGISTRY_HOST/v2/{{.CATALOG}}/tags/list
7778
silent: false
7879

7980
get-image:
@@ -86,7 +87,7 @@ tasks:
8687
sh: echo '{{.IMAGE}}' | cut -d':' -f2
8788
cmds:
8889
- echo "Getting image {{.IMAGE_NAME}} with hash {{.HASH}}"
89-
- http -a $REGISTRY_USER:$REGISTRY_PASS GET "${REGISTRY_HOST}/v2/{{.IMAGE_NAME}}/manifests/{{.HASH}}"
90+
- curl -u $REGISTRY_USER:$REGISTRY_PASS $REGISTRY_HOST/v2/{{.IMAGE_NAME}}/manifests/{{.HASH}}
9091
silent: false
9192

9293
delete-image:
@@ -98,9 +99,9 @@ tasks:
9899
HASH:
99100
sh: echo '{{.IMAGE}}' | cut -d':' -f2
100101
MANIFEST_DIGEST:
101-
sh: http --headers -a $REGISTRY_USER:$REGISTRY_PASS GET "${REGISTRY_HOST}/v2/{{.IMAGE_NAME}}/manifests/{{.HASH}}" | grep -i 'Docker-Content-Digest:' | awk '{print $2}' | tr -d '\r'
102+
sh: curl --silent -u $REGISTRY_USER:$REGISTRY_PASS $REGISTRY_HOST/v2/{{.IMAGE_NAME}}/manifests/{{.HASH}} | grep -i 'Docker-Content-Digest:' | awk '{print $2}' | tr -d '\r'
102103
cmds:
103104
- echo 'Deleting image {{.IMAGE}}'
104105
- echo "Deleting manifest {{.MANIFEST_DIGEST}} for image {{.IMAGE_NAME}}"
105-
- http -a $REGISTRY_USER:$REGISTRY_PASS DELETE "${REGISTRY_HOST}/v2/{{.IMAGE_NAME}}/manifests/{{.MANIFEST_DIGEST}}"
106+
- curl -u $REGISTRY_USER:$REGISTRY_PASS -X DELETE $REGISTRY_HOST/v2/{{.IMAGE_NAME}}/manifests/{{.MANIFEST_DIGEST}}
106107
silent: false

openserverless/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,5 @@ def log_request_info():
7979

8080
import openserverless.rest.api
8181
import openserverless.rest.auth
82+
import openserverless.rest.build
8283

openserverless/rest/api.py

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -17,73 +17,7 @@
1717
#
1818

1919
from openserverless import app
20-
from http import HTTPStatus
21-
from flask import request
22-
2320
import openserverless.common.response_builder as res_builder
24-
from openserverless.common.utils import env_to_dict
25-
from openserverless.error.api_error import AuthorizationError
26-
from openserverless.impl.builder.build_service import BuildService
27-
from openserverless.common.openwhisk_authorize import OpenwhiskAuthorize
28-
29-
@app.route('/system/build', methods=['POST'])
30-
def build():
31-
"""
32-
Build Endpoint
33-
---
34-
tags:
35-
- Build
36-
responses:
37-
200:
38-
description: Build Endpoint Returns Basic Configuration Data used by this API.
39-
schema:
40-
$ref: '#/definitions/Message'
41-
"""
42-
43-
normalized_headers = {key.lower(): value for key, value in request.headers.items()}
44-
auth_header = normalized_headers.get('authorization', None)
45-
46-
if auth_header is None:
47-
return res_builder.build_error_message("Missing authorization header", 401)
48-
49-
oa = OpenwhiskAuthorize()
50-
try:
51-
user_data = oa.login(auth_header)
52-
env = env_to_dict(user_data)
53-
if env is None:
54-
return res_builder.build_error_message("User environment not found", status_code=HTTPStatus.UNAUTHORIZED)
55-
56-
if (request.json is None):
57-
return res_builder.build_error_message("No JSON payload provided for build.", status_code=HTTPStatus.BAD_REQUEST)
58-
59-
json_data = request.json
60-
if 'source' not in json_data:
61-
return res_builder.build_error_message("No source provided for build.", status_code=HTTPStatus.BAD_REQUEST)
62-
if 'target' not in json_data:
63-
return res_builder.build_error_message("No target provided for build.", status_code=HTTPStatus.BAD_REQUEST)
64-
if 'kind' not in json_data:
65-
return res_builder.build_error_message("No kind provided for build.", status_code=HTTPStatus.BAD_REQUEST)
66-
67-
68-
# validate the target
69-
target = json_data.get('target')
70-
target_user = str(target).split(':')[0]
71-
if user_data.get('login') != target_user:
72-
return res_builder.build_error_message("Invalid target for the build.", status_code=HTTPStatus.BAD_REQUEST)
73-
74-
75-
build_service = BuildService(build_config=json_data, user_env=env)
76-
build_success = build_service.build(json_data.get('target')) # Replace with your desired image name
77-
78-
if not build_success:
79-
return res_builder.build_error_message("Build process failed.", status_code=HTTPStatus.INTERNAL_SERVER_ERROR)
80-
81-
return res_builder.build_response_message("Build process initiated successfully.", status_code=HTTPStatus.OK)
82-
83-
except AuthorizationError:
84-
return res_builder.build_error_message("Invalid authorization", 401)
85-
86-
8721

8822
@app.route('/system/info')
8923
def info():

openserverless/rest/auth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def password(login, **kwargs):
3535
summary: Login an OpenServerless user using login/password payload
3636
operationId: patchOpsUser
3737
security:
38-
- openwhiskBasicAuth: []
38+
- openwhiskBasicAuth: []
3939
consumes:
4040
- application/json
4141
definitions:

openserverless/rest/build.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
#
18+
from openserverless import app
19+
from http import HTTPStatus
20+
from flask import request
21+
22+
import openserverless.common.response_builder as res_builder
23+
from openserverless.common.utils import env_to_dict
24+
from openserverless.error.api_error import AuthorizationError
25+
from openserverless.impl.builder.build_service import BuildService
26+
from openserverless.common.openwhisk_authorize import OpenwhiskAuthorize
27+
28+
@app.route('/system/api/v1/build', methods=['POST'])
29+
def build():
30+
"""
31+
Build Endpoint
32+
---
33+
tags:
34+
- Build
35+
summary: Build an image using the provided source, target, and kind.
36+
description: This endpoint triggers a build process based on the provided parameters.
37+
operationId: buildImage
38+
security:
39+
- openwhiskBasicAuth: []
40+
consumes:
41+
- application/json
42+
parameters:
43+
- in: body
44+
name: BuildRequest
45+
required: true
46+
schema:
47+
type: object
48+
properties:
49+
source:
50+
type: string
51+
description: Source for the build
52+
target:
53+
type: string
54+
description: Target for the build
55+
kind:
56+
type: string
57+
description: Kind of the build
58+
responses:
59+
200:
60+
description: Build process initiated successfully.
61+
schema:
62+
$ref: '#/definitions/Message'
63+
400:
64+
description: Bad Request. Missing or invalid parameters.
65+
schema:
66+
$ref: '#/definitions/Message'
67+
401:
68+
description: Unauthorized. Invalid or missing authorization header.
69+
schema:
70+
$ref: '#/definitions/Message'
71+
500:
72+
description: Internal Server Error. Build process failed.
73+
schema:
74+
$ref: '#/definitions/Message'
75+
"""
76+
77+
normalized_headers = {key.lower(): value for key, value in request.headers.items()}
78+
auth_header = normalized_headers.get('authorization', None)
79+
80+
if auth_header is None:
81+
return res_builder.build_error_message("Missing authorization header", 401)
82+
83+
oa = OpenwhiskAuthorize()
84+
try:
85+
user_data = oa.login(auth_header)
86+
env = env_to_dict(user_data)
87+
if env is None:
88+
return res_builder.build_error_message("User environment not found", status_code=HTTPStatus.UNAUTHORIZED)
89+
90+
if (request.json is None):
91+
return res_builder.build_error_message("No JSON payload provided for build.", status_code=HTTPStatus.BAD_REQUEST)
92+
93+
json_data = request.json
94+
if 'source' not in json_data:
95+
return res_builder.build_error_message("No source provided for build.", status_code=HTTPStatus.BAD_REQUEST)
96+
if 'target' not in json_data:
97+
return res_builder.build_error_message("No target provided for build.", status_code=HTTPStatus.BAD_REQUEST)
98+
if 'kind' not in json_data:
99+
return res_builder.build_error_message("No kind provided for build.", status_code=HTTPStatus.BAD_REQUEST)
100+
101+
102+
# validate the target
103+
target = json_data.get('target')
104+
target_user = str(target).split(':')[0]
105+
if user_data.get('login') != target_user:
106+
return res_builder.build_error_message("Invalid target for the build.", status_code=HTTPStatus.BAD_REQUEST)
107+
108+
109+
build_service = BuildService(build_config=json_data, user_env=env)
110+
build_success = build_service.build(json_data.get('target')) # Replace with your desired image name
111+
112+
if not build_success:
113+
return res_builder.build_error_message("Build process failed.", status_code=HTTPStatus.INTERNAL_SERVER_ERROR)
114+
115+
return res_builder.build_response_message("Build process initiated successfully.", status_code=HTTPStatus.OK)
116+
117+
except AuthorizationError:
118+
return res_builder.build_error_message("Invalid authorization", 401)

0 commit comments

Comments
 (0)