port-ocean 0.5.5__py3-none-any.whl → 0.17.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of port-ocean might be problematic. Click here for more details.
- integrations/_infra/Dockerfile.Deb +56 -0
- integrations/_infra/Dockerfile.alpine +108 -0
- integrations/_infra/Dockerfile.base.builder +26 -0
- integrations/_infra/Dockerfile.base.runner +13 -0
- integrations/_infra/Dockerfile.dockerignore +94 -0
- {port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}} → integrations/_infra}/Makefile +21 -8
- integrations/_infra/grpcio.sh +18 -0
- integrations/_infra/init.sh +5 -0
- port_ocean/bootstrap.py +1 -1
- port_ocean/cli/commands/defaults/clean.py +3 -1
- port_ocean/cli/commands/new.py +42 -7
- port_ocean/cli/commands/sail.py +7 -1
- port_ocean/cli/cookiecutter/cookiecutter.json +3 -0
- port_ocean/cli/cookiecutter/hooks/post_gen_project.py +20 -3
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example +6 -0
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json +41 -0
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml +16 -0
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml +6 -7
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md +1 -1
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md +7 -0
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore +1 -0
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py +16 -1
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml +21 -10
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/test_sample.py +2 -0
- port_ocean/clients/port/authentication.py +16 -4
- port_ocean/clients/port/client.py +17 -0
- port_ocean/clients/port/mixins/blueprints.py +7 -8
- port_ocean/clients/port/mixins/entities.py +108 -53
- port_ocean/clients/port/mixins/integrations.py +23 -34
- port_ocean/clients/port/retry_transport.py +0 -5
- port_ocean/clients/port/utils.py +9 -3
- port_ocean/config/base.py +16 -16
- port_ocean/config/dynamic.py +2 -0
- port_ocean/config/settings.py +79 -11
- port_ocean/context/event.py +18 -5
- port_ocean/context/ocean.py +14 -3
- port_ocean/core/defaults/clean.py +10 -3
- port_ocean/core/defaults/common.py +25 -9
- port_ocean/core/defaults/initialize.py +111 -100
- port_ocean/core/event_listener/__init__.py +8 -0
- port_ocean/core/event_listener/base.py +49 -10
- port_ocean/core/event_listener/factory.py +9 -1
- port_ocean/core/event_listener/http.py +11 -3
- port_ocean/core/event_listener/kafka.py +24 -5
- port_ocean/core/event_listener/once.py +96 -4
- port_ocean/core/event_listener/polling.py +16 -14
- port_ocean/core/event_listener/webhooks_only.py +41 -0
- port_ocean/core/handlers/__init__.py +1 -2
- port_ocean/core/handlers/entities_state_applier/base.py +4 -1
- port_ocean/core/handlers/entities_state_applier/port/applier.py +29 -87
- port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py +5 -2
- port_ocean/core/handlers/entity_processor/base.py +26 -22
- port_ocean/core/handlers/entity_processor/jq_entity_processor.py +253 -45
- port_ocean/core/handlers/port_app_config/base.py +55 -15
- port_ocean/core/handlers/port_app_config/models.py +24 -5
- port_ocean/core/handlers/resync_state_updater/__init__.py +5 -0
- port_ocean/core/handlers/resync_state_updater/updater.py +84 -0
- port_ocean/core/integrations/base.py +5 -7
- port_ocean/core/integrations/mixins/events.py +3 -1
- port_ocean/core/integrations/mixins/sync.py +4 -2
- port_ocean/core/integrations/mixins/sync_raw.py +209 -74
- port_ocean/core/integrations/mixins/utils.py +1 -1
- port_ocean/core/models.py +44 -0
- port_ocean/core/ocean_types.py +29 -11
- port_ocean/core/utils/entity_topological_sorter.py +90 -0
- port_ocean/core/utils/utils.py +109 -0
- port_ocean/debug_cli.py +5 -0
- port_ocean/exceptions/core.py +4 -0
- port_ocean/exceptions/port_defaults.py +0 -2
- port_ocean/helpers/retry.py +85 -24
- port_ocean/log/handlers.py +23 -2
- port_ocean/log/logger_setup.py +8 -1
- port_ocean/log/sensetive.py +25 -10
- port_ocean/middlewares.py +10 -2
- port_ocean/ocean.py +57 -24
- port_ocean/run.py +10 -5
- port_ocean/tests/__init__.py +0 -0
- port_ocean/tests/clients/port/mixins/test_entities.py +53 -0
- port_ocean/tests/conftest.py +4 -0
- port_ocean/tests/core/defaults/test_common.py +166 -0
- port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py +350 -0
- port_ocean/tests/core/handlers/mixins/test_sync_raw.py +552 -0
- port_ocean/tests/core/test_utils.py +73 -0
- port_ocean/tests/core/utils/test_entity_topological_sorter.py +99 -0
- port_ocean/tests/helpers/__init__.py +0 -0
- port_ocean/tests/helpers/fake_port_api.py +191 -0
- port_ocean/tests/helpers/fixtures.py +46 -0
- port_ocean/tests/helpers/integration.py +31 -0
- port_ocean/tests/helpers/ocean_app.py +66 -0
- port_ocean/tests/helpers/port_client.py +21 -0
- port_ocean/tests/helpers/smoke_test.py +82 -0
- port_ocean/tests/log/test_handlers.py +71 -0
- port_ocean/tests/test_smoke.py +74 -0
- port_ocean/tests/utils/test_async_iterators.py +45 -0
- port_ocean/tests/utils/test_cache.py +189 -0
- port_ocean/utils/async_iterators.py +109 -0
- port_ocean/utils/cache.py +37 -1
- port_ocean/utils/misc.py +22 -4
- port_ocean/utils/queue_utils.py +88 -0
- port_ocean/utils/signal.py +1 -4
- port_ocean/utils/time.py +54 -0
- {port_ocean-0.5.5.dist-info → port_ocean-0.17.8.dist-info}/METADATA +27 -19
- port_ocean-0.17.8.dist-info/RECORD +164 -0
- {port_ocean-0.5.5.dist-info → port_ocean-0.17.8.dist-info}/WHEEL +1 -1
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.dockerignore +0 -94
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/Dockerfile +0 -15
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/config.yaml +0 -17
- port_ocean/core/handlers/entities_state_applier/port/validate_entity_relations.py +0 -40
- port_ocean/core/utils.py +0 -65
- port_ocean-0.5.5.dist-info/RECORD +0 -129
- {port_ocean-0.5.5.dist-info → port_ocean-0.17.8.dist-info}/LICENSE.md +0 -0
- {port_ocean-0.5.5.dist-info → port_ocean-0.17.8.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
ARG BASE_BUILDER_PYTHON_IMAGE=ghcr.io/port-labs/port-ocean-base-builder:latest
|
|
2
|
+
ARG BASE_RUNNER_PYTHON_IMAGE=ghcr.io/port-labs/port-ocean-base-runner:latest
|
|
3
|
+
|
|
4
|
+
FROM ${BASE_BUILDER_PYTHON_IMAGE} AS base
|
|
5
|
+
|
|
6
|
+
ARG BUILD_CONTEXT
|
|
7
|
+
ARG BUILDPLATFORM
|
|
8
|
+
|
|
9
|
+
ENV LIBRDKAFKA_VERSION=1.9.2 \
|
|
10
|
+
PYTHONUNBUFFERED=1 \
|
|
11
|
+
POETRY_VIRTUALENVS_IN_PROJECT=1 \
|
|
12
|
+
PIP_ROOT_USER_ACTION=ignore
|
|
13
|
+
|
|
14
|
+
WORKDIR /app
|
|
15
|
+
|
|
16
|
+
COPY ./${BUILD_CONTEXT}/pyproject.toml ./${BUILD_CONTEXT}/poetry.lock /app/
|
|
17
|
+
|
|
18
|
+
RUN poetry install --without dev --no-root --no-interaction --no-ansi --no-cache
|
|
19
|
+
|
|
20
|
+
FROM ${BASE_RUNNER_PYTHON_IMAGE} AS prod
|
|
21
|
+
|
|
22
|
+
ARG INTEGRATION_VERSION
|
|
23
|
+
ARG BUILD_CONTEXT
|
|
24
|
+
|
|
25
|
+
ENV LIBRDKAFKA_VERSION=1.9.2
|
|
26
|
+
|
|
27
|
+
RUN apt-get update \
|
|
28
|
+
&& apt-get install -y \
|
|
29
|
+
ca-certificates \
|
|
30
|
+
openssl \
|
|
31
|
+
curl \
|
|
32
|
+
&& apt-get clean
|
|
33
|
+
|
|
34
|
+
LABEL INTEGRATION_VERSION=${INTEGRATION_VERSION}
|
|
35
|
+
# Used to ensure that new integrations will be public, see https://docs.github.com/en/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility
|
|
36
|
+
LABEL org.opencontainers.image.source=https://github.com/port-labs/ocean
|
|
37
|
+
|
|
38
|
+
ENV PIP_ROOT_USER_ACTION=ignore
|
|
39
|
+
|
|
40
|
+
WORKDIR /app
|
|
41
|
+
|
|
42
|
+
# Copy the application code
|
|
43
|
+
COPY ./${BUILD_CONTEXT} /app
|
|
44
|
+
|
|
45
|
+
# Copy dependencies from the build stage
|
|
46
|
+
COPY --from=base /app/.venv /app/.venv
|
|
47
|
+
|
|
48
|
+
COPY ./integrations/_infra/init.sh /app/init.sh
|
|
49
|
+
|
|
50
|
+
# Ensure that ocean is available for all in path
|
|
51
|
+
RUN chmod a+x /app/.venv/bin/ocean
|
|
52
|
+
|
|
53
|
+
RUN chmod a+x /app/init.sh
|
|
54
|
+
RUN ln -s /app/.venv/bin/ocean /usr/bin/ocean
|
|
55
|
+
# Run the application
|
|
56
|
+
CMD ["bash", "/app/init.sh"]
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
ARG BASE_PYTHON_IMAGE=alpine:3.20.1
|
|
2
|
+
|
|
3
|
+
FROM ${BASE_PYTHON_IMAGE} AS base
|
|
4
|
+
|
|
5
|
+
ARG BUILD_CONTEXT
|
|
6
|
+
ARG BUILDPLATFORM
|
|
7
|
+
|
|
8
|
+
ENV LIBRDKAFKA_VERSION=1.9.2 \
|
|
9
|
+
PYTHONUNBUFFERED=1 \
|
|
10
|
+
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
|
11
|
+
POETRY_NO_INTERACTION=1 \
|
|
12
|
+
PIP_NO_CACHE_DIR=on \
|
|
13
|
+
PIP_DEFAULT_TIMEOUT=100 \
|
|
14
|
+
GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY=1 \
|
|
15
|
+
PYTHONDONTWRITEBYTECODE=1
|
|
16
|
+
|
|
17
|
+
# Install system dependencies and libraries
|
|
18
|
+
RUN \
|
|
19
|
+
apk add --no-cache \
|
|
20
|
+
gcc \
|
|
21
|
+
g++ \
|
|
22
|
+
musl-dev \
|
|
23
|
+
build-base \
|
|
24
|
+
bash \
|
|
25
|
+
oniguruma-dev \
|
|
26
|
+
make \
|
|
27
|
+
autoconf \
|
|
28
|
+
automake \
|
|
29
|
+
libtool \
|
|
30
|
+
curl \
|
|
31
|
+
openssl-dev \
|
|
32
|
+
cargo \
|
|
33
|
+
pkgconfig \
|
|
34
|
+
linux-headers \
|
|
35
|
+
libstdc++ \
|
|
36
|
+
libffi-dev \
|
|
37
|
+
py3-grpcio \
|
|
38
|
+
py3-protobuf \
|
|
39
|
+
python3-dev \
|
|
40
|
+
# librdkafka-dev \
|
|
41
|
+
# Install community librdkafka-dev since the default in alpine is older
|
|
42
|
+
&& echo "@edge http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories \
|
|
43
|
+
&& echo "@edgecommunity http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \
|
|
44
|
+
&& apk add --no-cache \
|
|
45
|
+
alpine-sdk \
|
|
46
|
+
"librdkafka@edgecommunity>=${LIBRDKAFKA_VERSION}" \
|
|
47
|
+
"librdkafka-dev@edgecommunity>=${LIBRDKAFKA_VERSION}" \
|
|
48
|
+
&& curl -sSL https://install.python-poetry.org | python3 - \
|
|
49
|
+
&& apk upgrade gcc linux-headers libstdc++ gcc g++ --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main/ \
|
|
50
|
+
&& ln -s /root/.local/bin/poetry /usr/bin/poetry \
|
|
51
|
+
&& poetry config virtualenvs.in-project true
|
|
52
|
+
|
|
53
|
+
WORKDIR /app
|
|
54
|
+
|
|
55
|
+
COPY ./${BUILD_CONTEXT}/pyproject.toml ./${BUILD_CONTEXT}/poetry.lock /app/
|
|
56
|
+
|
|
57
|
+
COPY ./integrations/_infra/grpcio.sh /app/grpcio.sh
|
|
58
|
+
|
|
59
|
+
RUN chmod a+x /app/grpcio.sh && /app/grpcio.sh "${BUILDPLATFORM}"
|
|
60
|
+
|
|
61
|
+
RUN export GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY=1 \
|
|
62
|
+
&& poetry install --without dev --no-root --no-interaction --no-ansi --no-cache
|
|
63
|
+
|
|
64
|
+
FROM ${BASE_PYTHON_IMAGE} AS prod
|
|
65
|
+
|
|
66
|
+
ARG INTEGRATION_VERSION
|
|
67
|
+
ARG BUILD_CONTEXT
|
|
68
|
+
|
|
69
|
+
ENV LIBRDKAFKA_VERSION=1.9.2
|
|
70
|
+
|
|
71
|
+
LABEL INTEGRATION_VERSION=${INTEGRATION_VERSION}
|
|
72
|
+
# Used to ensure that new integrations will be public, see https://docs.github.com/en/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility
|
|
73
|
+
LABEL org.opencontainers.image.source=https://github.com/port-labs/ocean
|
|
74
|
+
|
|
75
|
+
# Install only runtime dependencies
|
|
76
|
+
RUN \
|
|
77
|
+
apk add --no-cache \
|
|
78
|
+
bash \
|
|
79
|
+
oniguruma-dev \
|
|
80
|
+
python3 \
|
|
81
|
+
# Install community librdkafka-dev since the default in alpine is older
|
|
82
|
+
&& echo "@edge http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories \
|
|
83
|
+
&& echo "@edgecommunity http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \
|
|
84
|
+
&& apk update \
|
|
85
|
+
&& apk add --no-cache \
|
|
86
|
+
alpine-sdk \
|
|
87
|
+
"librdkafka@edgecommunity>=${LIBRDKAFKA_VERSION}" \
|
|
88
|
+
"librdkafka-dev@edgecommunity>=${LIBRDKAFKA_VERSION}" \
|
|
89
|
+
# Fix security issues
|
|
90
|
+
&& apk upgrade busybox libcrypto3 libssl3 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main/
|
|
91
|
+
|
|
92
|
+
WORKDIR /app
|
|
93
|
+
|
|
94
|
+
# Copy the application code
|
|
95
|
+
COPY ./${BUILD_CONTEXT} /app
|
|
96
|
+
|
|
97
|
+
# Copy dependencies from the build stage
|
|
98
|
+
COPY --from=base /app/.venv /app/.venv
|
|
99
|
+
|
|
100
|
+
COPY ./integrations/_infra/init.sh /app/init.sh
|
|
101
|
+
|
|
102
|
+
# Ensure that ocean is available for all in path
|
|
103
|
+
RUN chmod a+x /app/.venv/bin/ocean
|
|
104
|
+
|
|
105
|
+
RUN chmod a+x /app/init.sh
|
|
106
|
+
RUN ln -s /app/.venv/bin/ocean /usr/bin/ocean
|
|
107
|
+
# Run the application
|
|
108
|
+
CMD ["bash", "/app/init.sh"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
ARG BASE_PYTHON_IMAGE=debian:trixie-slim
|
|
2
|
+
# debian:trixie-slim - Python 3.12
|
|
3
|
+
FROM ${BASE_PYTHON_IMAGE}
|
|
4
|
+
|
|
5
|
+
LABEL org.opencontainers.image.source=https://github.com/port-labs/ocean
|
|
6
|
+
|
|
7
|
+
ENV LIBRDKAFKA_VERSION=1.9.2 \
|
|
8
|
+
PYTHONUNBUFFERED=1 \
|
|
9
|
+
POETRY_VIRTUALENVS_IN_PROJECT=1 \
|
|
10
|
+
PIP_ROOT_USER_ACTION=ignore
|
|
11
|
+
|
|
12
|
+
RUN apt-get update \
|
|
13
|
+
&& apt-get install -y \
|
|
14
|
+
--no-install-recommends \
|
|
15
|
+
wget \
|
|
16
|
+
g++ \
|
|
17
|
+
libssl-dev \
|
|
18
|
+
autoconf \
|
|
19
|
+
automake \
|
|
20
|
+
libtool \
|
|
21
|
+
curl \
|
|
22
|
+
librdkafka-dev \
|
|
23
|
+
python3 \
|
|
24
|
+
python3-pip \
|
|
25
|
+
python3-poetry \
|
|
26
|
+
&& apt-get clean
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ARG BASE_PYTHON_IMAGE=debian:trixie-slim
|
|
2
|
+
# debian:trixie-slim - Python 3.12
|
|
3
|
+
FROM ${BASE_PYTHON_IMAGE}
|
|
4
|
+
|
|
5
|
+
LABEL org.opencontainers.image.source=https://github.com/port-labs/ocean
|
|
6
|
+
|
|
7
|
+
ENV LIBRDKAFKA_VERSION=1.9.2
|
|
8
|
+
|
|
9
|
+
ENV PIP_ROOT_USER_ACTION=ignore
|
|
10
|
+
|
|
11
|
+
RUN apt-get update \
|
|
12
|
+
&& apt-get install -y --no-install-recommends librdkafka-dev python3 \
|
|
13
|
+
&& apt-get clean
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
|
|
2
|
+
# Git
|
|
3
|
+
**/.git
|
|
4
|
+
**/.gitignore
|
|
5
|
+
**/.gitattributes
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# CI
|
|
9
|
+
**/.codeclimate.yml
|
|
10
|
+
**/.travis.yml
|
|
11
|
+
**/.taskcluster.yml
|
|
12
|
+
|
|
13
|
+
# Docker
|
|
14
|
+
**/docker-compose.yml
|
|
15
|
+
**/Dockerfile
|
|
16
|
+
**/.docker
|
|
17
|
+
**/.dockerignore
|
|
18
|
+
|
|
19
|
+
# Byte-compiled / optimized / DLL files
|
|
20
|
+
**/__pycache__/
|
|
21
|
+
**/*.py[cod]
|
|
22
|
+
|
|
23
|
+
# C extensions
|
|
24
|
+
**/*.so
|
|
25
|
+
|
|
26
|
+
# Distribution / packaging
|
|
27
|
+
**/.Python
|
|
28
|
+
**/env/
|
|
29
|
+
**/build/
|
|
30
|
+
**/develop-eggs/
|
|
31
|
+
**/dist/
|
|
32
|
+
**/downloads/
|
|
33
|
+
**/eggs/
|
|
34
|
+
**/lib/
|
|
35
|
+
**/lib64/
|
|
36
|
+
**/parts/
|
|
37
|
+
**/sdist/
|
|
38
|
+
**/var/
|
|
39
|
+
**/*.egg-info/
|
|
40
|
+
**/.installed.cfg
|
|
41
|
+
**/*.egg
|
|
42
|
+
|
|
43
|
+
# PyInstaller
|
|
44
|
+
# Usually these files are written by a python script from a template
|
|
45
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
46
|
+
**/*.manifest
|
|
47
|
+
**/*.spec
|
|
48
|
+
|
|
49
|
+
# Installer logs
|
|
50
|
+
**/pip-log.txt
|
|
51
|
+
**/pip-delete-this-directory.txt
|
|
52
|
+
|
|
53
|
+
# Unit test / coverage reports
|
|
54
|
+
**/htmlcov/
|
|
55
|
+
**/.tox/
|
|
56
|
+
**/.coverage
|
|
57
|
+
**/.cache
|
|
58
|
+
**/nosetests.xml
|
|
59
|
+
**/coverage.xml
|
|
60
|
+
|
|
61
|
+
# Translations
|
|
62
|
+
**/*.mo
|
|
63
|
+
**/*.pot
|
|
64
|
+
|
|
65
|
+
# Django stuff:
|
|
66
|
+
**/*.log
|
|
67
|
+
|
|
68
|
+
# Sphinx documentation
|
|
69
|
+
**/docs/_build/
|
|
70
|
+
|
|
71
|
+
# PyBuilder
|
|
72
|
+
**/target/
|
|
73
|
+
|
|
74
|
+
# Virtual environment
|
|
75
|
+
**/.env
|
|
76
|
+
**/.venv/
|
|
77
|
+
**/venv/
|
|
78
|
+
|
|
79
|
+
# PyCharm
|
|
80
|
+
**/.idea
|
|
81
|
+
|
|
82
|
+
# Python mode for VIM
|
|
83
|
+
**/.ropeproject
|
|
84
|
+
|
|
85
|
+
# Vim swap files
|
|
86
|
+
**/*.swp
|
|
87
|
+
|
|
88
|
+
# VS Code
|
|
89
|
+
**/.vscode/
|
|
90
|
+
|
|
91
|
+
**/*.md
|
|
92
|
+
**/.ruff_cache
|
|
93
|
+
**/changelog
|
|
94
|
+
**/tests
|
{port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}} → integrations/_infra}/Makefile
RENAMED
|
@@ -3,9 +3,13 @@ ACTIVATE := . .venv/bin/activate
|
|
|
3
3
|
define run_checks
|
|
4
4
|
exit_code=0; \
|
|
5
5
|
cd $1; \
|
|
6
|
+
echo "Running poetry check"; \
|
|
6
7
|
poetry check || exit_code=$$?;\
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
echo "Running mypy"; \
|
|
9
|
+
mypy . --exclude '/\.venv/' || exit_code=$$?; \
|
|
10
|
+
echo "Running ruff"; \
|
|
11
|
+
ruff check . || exit_code=$$?; \
|
|
12
|
+
echo "Running black"; \
|
|
9
13
|
black --check . || exit_code=$$?; \
|
|
10
14
|
if [ $$exit_code -eq 1 ]; then \
|
|
11
15
|
echo "\033[0;31mOne or more checks failed with exit code $$exit_code\033[0m"; \
|
|
@@ -18,7 +22,7 @@ endef
|
|
|
18
22
|
define install_poetry
|
|
19
23
|
if ! command -v poetry &> /dev/null; then \
|
|
20
24
|
pip install --upgrade pip; \
|
|
21
|
-
pip install poetry; \
|
|
25
|
+
pip install 'poetry>=1.0.0,<2.0.0'; \
|
|
22
26
|
else \
|
|
23
27
|
echo "Poetry is already installed."; \
|
|
24
28
|
fi
|
|
@@ -37,26 +41,35 @@ define deactivate_virtualenv
|
|
|
37
41
|
fi
|
|
38
42
|
endef
|
|
39
43
|
|
|
40
|
-
.SILENT: install install/prod lint run test clean
|
|
44
|
+
.SILENT: install install/prod install/local-core lint lint/fix run test clean
|
|
41
45
|
|
|
42
46
|
install:
|
|
43
47
|
$(call deactivate_virtualenv) && \
|
|
44
48
|
$(call install_poetry) && \
|
|
45
49
|
poetry install --with dev
|
|
46
50
|
|
|
51
|
+
install/local-core: install
|
|
52
|
+
# NOTE: This is a temporary change that shouldn't be committed
|
|
53
|
+
$(ACTIVATE) && pip install -e ../../
|
|
54
|
+
|
|
47
55
|
install/prod:
|
|
48
|
-
$(call install_poetry) && \
|
|
49
56
|
poetry install --without dev --no-root --no-interaction --no-ansi --no-cache
|
|
57
|
+
$(call install_poetry) && \
|
|
50
58
|
|
|
51
59
|
lint:
|
|
52
60
|
$(ACTIVATE) && \
|
|
53
61
|
$(call run_checks,.)
|
|
54
62
|
|
|
63
|
+
lint/fix:
|
|
64
|
+
$(ACTIVATE) && \
|
|
65
|
+
black .
|
|
66
|
+
ruff check --fix .
|
|
67
|
+
|
|
55
68
|
run:
|
|
56
69
|
$(ACTIVATE) && ocean sail
|
|
57
70
|
|
|
58
|
-
test:
|
|
59
|
-
$(ACTIVATE) && poetry run pytest
|
|
71
|
+
test:
|
|
72
|
+
$(ACTIVATE) && poetry run pytest -n auto
|
|
60
73
|
|
|
61
74
|
clean:
|
|
62
75
|
@find . -name '.venv' -type d -exec rm -rf {} \;
|
|
@@ -71,4 +84,4 @@ clean:
|
|
|
71
84
|
rm -rf htmlcov
|
|
72
85
|
rm -rf .tox/
|
|
73
86
|
rm -rf docs/_build
|
|
74
|
-
rm -rf dist/
|
|
87
|
+
rm -rf dist/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
PLATFORM=${1}
|
|
3
|
+
|
|
4
|
+
if [[ ! $(grep -q 'grpcio' ./poetry.lock) ]]; then
|
|
5
|
+
echo 'grpcio not present, skipping explicit build'
|
|
6
|
+
else
|
|
7
|
+
echo 'found grpcio, checking platform'
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
if [[ "${PLATFORM}" == "linux/arm64" ]]; then
|
|
11
|
+
echo "On arm, need to explicitly install grpcio"
|
|
12
|
+
poetry env use "$(which python)"
|
|
13
|
+
echo "${VIRTUAL_ENV}"
|
|
14
|
+
poetry run pip install --upgrade pip
|
|
15
|
+
GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1 GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY=1 poetry run pip install 'grpcio==1.66.2'
|
|
16
|
+
else
|
|
17
|
+
echo "Not on arm, no need to explicitly install grpcio"
|
|
18
|
+
fi
|
port_ocean/bootstrap.py
CHANGED
port_ocean/cli/commands/new.py
CHANGED
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
|
|
3
6
|
import click
|
|
4
7
|
from cookiecutter.main import cookiecutter # type: ignore
|
|
5
8
|
|
|
6
|
-
from port_ocean.cli.commands.main import cli_start,
|
|
9
|
+
from port_ocean.cli.commands.main import cli_start, console, print_logo
|
|
7
10
|
from port_ocean.cli.utils import cli_root_path
|
|
8
11
|
|
|
9
12
|
|
|
13
|
+
def add_vscode_configuration(result: str, name: str) -> None:
|
|
14
|
+
vscode_entry_root_path = "${workspaceFolder}/integrations/" + name
|
|
15
|
+
new_vscode_entry = {
|
|
16
|
+
"console": "integratedTerminal",
|
|
17
|
+
"cwd": vscode_entry_root_path,
|
|
18
|
+
"envFile": f"{vscode_entry_root_path}/.env",
|
|
19
|
+
"justMyCode": True,
|
|
20
|
+
"name": f"Run {name} integration",
|
|
21
|
+
"program": f"{vscode_entry_root_path}/debug.py",
|
|
22
|
+
"python": f"{vscode_entry_root_path}/.venv/bin/python",
|
|
23
|
+
"request": "launch",
|
|
24
|
+
"type": "debugpy",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
vs_code_json_path = os.path.join(os.path.dirname(result), "../.vscode/launch.json")
|
|
28
|
+
if not os.path.exists(vs_code_json_path):
|
|
29
|
+
return
|
|
30
|
+
vs_code_json = json.load(open(vs_code_json_path, "r"))
|
|
31
|
+
vs_code_json["configurations"].append(new_vscode_entry)
|
|
32
|
+
|
|
33
|
+
with open(vs_code_json_path, "w") as vs_code_json_file:
|
|
34
|
+
json.dump(vs_code_json, vs_code_json_file, indent=2)
|
|
35
|
+
vs_code_json_file.write("\n")
|
|
36
|
+
|
|
37
|
+
|
|
10
38
|
@cli_start.command()
|
|
11
39
|
@click.argument("path", default=".", type=click.Path(exists=True))
|
|
12
40
|
@click.option(
|
|
@@ -35,22 +63,29 @@ def new(path: str, is_private_integration: bool) -> None:
|
|
|
35
63
|
"is_private_integration": is_private_integration,
|
|
36
64
|
},
|
|
37
65
|
)
|
|
66
|
+
|
|
38
67
|
name = result.split("/")[-1]
|
|
39
68
|
|
|
69
|
+
final_private_integration = os.path.exists(os.path.join(result, "Dockerfile"))
|
|
70
|
+
|
|
71
|
+
if not final_private_integration:
|
|
72
|
+
add_vscode_configuration(result, name)
|
|
73
|
+
|
|
40
74
|
console.print(
|
|
41
75
|
"\n🌊 Ahoy, Captain! Your project is ready to set sail into the vast ocean of possibilities!",
|
|
42
76
|
style="bold",
|
|
43
77
|
)
|
|
44
78
|
console.print("Here are your next steps:\n", style="bold")
|
|
45
79
|
console.print(
|
|
46
|
-
"⚓️ Install necessary packages: Run [bold][blue]make install[/blue][/bold] to install all required packages for your project
|
|
47
|
-
f"▶️ [bold][blue]cd {path}/{name} && make install && . .venv/bin/activate[/blue][/bold]\n"
|
|
80
|
+
f"⚓️ Install necessary packages: Run [bold][blue]cd {path}/{name} && make install && . .venv/bin/activate[/blue][/bold] to install all required packages for your project."
|
|
48
81
|
)
|
|
49
82
|
console.print(
|
|
50
|
-
"⚓️
|
|
51
|
-
f"▶️ [bold][blue]ocean sail {path}/{name}[/blue][/bold] \n"
|
|
83
|
+
"⚓️ Copy example env file: Run [bold][blue]cp .env.example .env [/blue][/bold] and update your integration's configuration in the .env file."
|
|
52
84
|
)
|
|
53
85
|
console.print(
|
|
54
|
-
"⚓️
|
|
55
|
-
f"▶️ [bold][blue]make run {path}/{name}[/blue][/bold]"
|
|
86
|
+
"⚓️ Set sail with [blue]Ocean[/blue]: Run [bold][blue]ocean sail[/blue][/bold] to run the project using Ocean."
|
|
56
87
|
)
|
|
88
|
+
if not final_private_integration:
|
|
89
|
+
console.print(
|
|
90
|
+
f"⚓️ Smooth sailing with [blue]Make[/blue]: Alternatively, you can run [bold][blue]make run {path}/{name}[/blue][/bold] to launch your project using Make."
|
|
91
|
+
)
|
port_ocean/cli/commands/sail.py
CHANGED
|
@@ -71,4 +71,10 @@ def sail(
|
|
|
71
71
|
console.print("Setting event listener to Once")
|
|
72
72
|
override["event_listener"] = {"type": "ONCE"}
|
|
73
73
|
|
|
74
|
-
run(
|
|
74
|
+
run(
|
|
75
|
+
path,
|
|
76
|
+
log_level,
|
|
77
|
+
port,
|
|
78
|
+
initialize_port_resources=initialize_port_resources,
|
|
79
|
+
config_override=override,
|
|
80
|
+
)
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
"email": "Your address email <you@example.com>",
|
|
7
7
|
"release_date": "{% now 'local' %}",
|
|
8
8
|
"is_private_integration": true,
|
|
9
|
+
"port_client_id": "you can find it using: https://docs.getport.io/build-your-software-catalog/custom-integration/api/#find-your-port-credentials",
|
|
10
|
+
"port_client_secret": "you can find it using: https://docs.getport.io/build-your-software-catalog/custom-integration/api/#find-your-port-credentials",
|
|
11
|
+
"is_us_region": false,
|
|
9
12
|
"_extensions": [
|
|
10
13
|
"jinja2_time.TimeExtension",
|
|
11
14
|
"extensions.VersionExtension"
|
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import shutil
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def handle_private_integration_flags():
|
|
6
|
+
target_dir = os.path.join(
|
|
7
|
+
"{{cookiecutter._output_dir}}", "{{cookiecutter.integration_slug}}"
|
|
8
|
+
)
|
|
9
|
+
root_dir = os.path.join("{{ cookiecutter._repo_dir }}", "../../../")
|
|
10
|
+
infra_make_file = os.path.join(root_dir, "integrations/_infra/Makefile")
|
|
11
|
+
infra_dockerfile = os.path.join(root_dir, "integrations/_infra/Dockerfile.deb")
|
|
12
|
+
infra_dockerignore = os.path.join(
|
|
13
|
+
root_dir, "integrations/_infra/Dockerfile.dockerignore"
|
|
14
|
+
)
|
|
15
|
+
target_link_make_file = os.path.join(target_dir, "./Makefile")
|
|
16
|
+
target_link_dockerfile = os.path.join(target_dir, "./Dockerfile")
|
|
17
|
+
target_link_dockerignore = os.path.join(target_dir, "./.dockerignore")
|
|
18
|
+
|
|
5
19
|
if "{{ cookiecutter.is_private_integration }}" == "True":
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
20
|
+
shutil.copyfile(infra_make_file, target_link_make_file)
|
|
21
|
+
shutil.copyfile(infra_dockerfile, target_link_dockerfile)
|
|
22
|
+
shutil.copyfile(infra_dockerignore, target_link_dockerignore)
|
|
9
23
|
os.remove("sonar-project.properties")
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
os.symlink(infra_make_file, target_link_make_file)
|
|
10
27
|
|
|
11
28
|
|
|
12
29
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
OCEAN__PORT__CLIENT_ID={{ cookiecutter.port_client_id }}
|
|
2
|
+
OCEAN__PORT__CLIENT_SECRET={{ cookiecutter.port_client_secret }}
|
|
3
|
+
OCEAN__INTEGRATION__IDENTIFIER={{ cookiecutter.integration_slug }}
|
|
4
|
+
OCEAN__PORT__BASE_URL={% if cookiecutter.is_us_region %}https://api.us.getport.io{% else %}https://api.getport.io{% endif %}
|
|
5
|
+
OCEAN__EVENT_LISTENER__TYPE=POLLING
|
|
6
|
+
OCEAN__INITIALIZE_PORT_RESOURCES=true
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"identifier": "{{ cookiecutter.integration_slug }}ExampleBlueprint",
|
|
4
|
+
"title": "{{ cookiecutter.integration_name }} Example",
|
|
5
|
+
"icon": "Blueprint",
|
|
6
|
+
"schema": {
|
|
7
|
+
"properties": {
|
|
8
|
+
"status": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"enum": [
|
|
11
|
+
"VALID",
|
|
12
|
+
"FAILED"
|
|
13
|
+
],
|
|
14
|
+
"enumColors": {
|
|
15
|
+
"VALID": "green",
|
|
16
|
+
"FAILED": "red"
|
|
17
|
+
},
|
|
18
|
+
"title": "Status"
|
|
19
|
+
},
|
|
20
|
+
"text": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"title": "Text"
|
|
23
|
+
},
|
|
24
|
+
"component": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"title": "Component"
|
|
27
|
+
},
|
|
28
|
+
"service": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"title": "Service"
|
|
31
|
+
},
|
|
32
|
+
"score": {
|
|
33
|
+
"type": "number",
|
|
34
|
+
"title": "Score"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"required": []
|
|
38
|
+
},
|
|
39
|
+
"relations": {}
|
|
40
|
+
}
|
|
41
|
+
]
|
port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
resources:
|
|
2
|
+
- kind: {{ cookiecutter.integration_slug}}-example-kind
|
|
3
|
+
selector:
|
|
4
|
+
query: 'true'
|
|
5
|
+
port:
|
|
6
|
+
entity:
|
|
7
|
+
mappings:
|
|
8
|
+
identifier: .my_custom_id
|
|
9
|
+
title: '(.my_component + " @ " + .my_service)'
|
|
10
|
+
blueprint: '"{{ cookiecutter.integration_slug }}ExampleBlueprint"'
|
|
11
|
+
properties:
|
|
12
|
+
status: .my_enum
|
|
13
|
+
text: .my_custom_text
|
|
14
|
+
component: .my_component
|
|
15
|
+
service: .my_service
|
|
16
|
+
score: .my_special_score
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
type: {{cookiecutter.integration_slug}}
|
|
2
1
|
description: {{cookiecutter.integration_name}} integration for Port Ocean
|
|
3
|
-
icon: Cookiecutter
|
|
2
|
+
icon: Cookiecutter # Should be one of the available icons in Port
|
|
4
3
|
features:
|
|
5
4
|
- type: exporter
|
|
6
|
-
section:
|
|
5
|
+
section: Under Development # Should be one of the available sections in Port
|
|
7
6
|
resources:
|
|
8
|
-
- kind:
|
|
9
|
-
- kind: <ResourceName2>
|
|
7
|
+
- kind: {{ cookiecutter.integration_slug }}-example-kind
|
|
8
|
+
# - kind: <ResourceName2>
|
|
10
9
|
configurations:
|
|
11
|
-
- name:
|
|
12
|
-
required: true
|
|
10
|
+
- name: my{{ cookiecutter.integration_slug}}Token
|
|
11
|
+
# required: true
|
|
13
12
|
type: string
|
|
14
13
|
sensitive: true
|
|
15
14
|
- name: someApplicationUrl
|