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

Merge Stable (@0.15.3) to Develop #4097

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b21b674
Fix using HFID for relationships when creating new nodes (#3966)
gmazoyer Jul 31, 2024
b2da9b8
Get HFID for related node to avoid calling fetch (#3976)
gmazoyer Jul 31, 2024
8917038
Validate HFID/uniqueness constraint format (#3972)
gmazoyer Jul 31, 2024
6173ac1
Update Infrahub to 0.15.2 and Python SDK to 0.12.2 (#3978)
gmazoyer Jul 31, 2024
d30cea0
Fix attribute uniqueness validator to not run in isolated mode
ogenstad Aug 7, 2024
4a29a35
set up plumbing and documentation for `towncrier` (#4021)
lykinsbd Aug 7, 2024
69c0d09
Avoid running attribute uniqueness check on schema attributes
ogenstad Aug 8, 2024
e37d577
Revert 3792 by storing profiles relationship in the db
dgarros Aug 4, 2024
8151e2f
Fix format
dgarros Aug 4, 2024
eac3d14
Add towncrier as dev dependency
ogenstad Aug 8, 2024
8fb157f
update getting-started/branches (#4014)
petercrocker Aug 8, 2024
a202071
Merge pull request #4026 from opsmill/pog-attribute-unique-validator
ogenstad Aug 8, 2024
6ca700b
Merge pull request #4029 from opsmill/pog-schema-integrity-attribute
ogenstad Aug 8, 2024
0c3af51
Merge pull request #4031 from opsmill/pog-pick-schema-inconsistency
ogenstad Aug 8, 2024
78ae7b3
Merge pull request #4032 from opsmill/pog-add-towncrier-package
ogenstad Aug 8, 2024
e09b0ca
Fix some docs typo (#4035)
BeArchiTek Aug 8, 2024
0b9ea98
Add towncrier newsfragments for resolved issues
ogenstad Aug 8, 2024
a9a351f
Merge pull request #4037 from opsmill/pog-towncrier
ogenstad Aug 9, 2024
7d09997
Make schema integrity check messages more user-friendly
ogenstad Aug 8, 2024
e038841
Add newsfragment for #4025
ogenstad Aug 9, 2024
20e11bb
Merge pull request #4033 from opsmill/pog-friendlier-schema-integrity…
ogenstad Aug 9, 2024
e928c1a
Merge pull request #4045 from opsmill/pog-4025-newscrier
ogenstad Aug 9, 2024
59775a0
Towncrier fragment for #4035 (#4048)
BeArchiTek Aug 9, 2024
b598072
Fix uniqueness constraint with enum attribute (#4050)
gmazoyer Aug 9, 2024
72d9109
Add CICD job to update helm/chart.yaml (#4044)
BeArchiTek Aug 9, 2024
91f0da5
Profile type select update to display informations on the related nod…
pa-lem Aug 9, 2024
89e2d63
IFC-248 - Branch parameters in SDK (#4056)
BeArchiTek Aug 9, 2024
e63b27a
Backport fix for inherited attribute / relationships not being update…
gmazoyer Aug 12, 2024
0eddeb1
bump sdk from 0.12.2 to 0.12.3 (#4061)
BeArchiTek Aug 12, 2024
e5d46e0
Serve Swagger & Redoc files locally so that the REST-API docs work of…
ogenstad Aug 12, 2024
bf2bfae
Merge pull request #4065 from opsmill/pog-rest-api-docs-offline
ogenstad Aug 12, 2024
1374fa4
Allow enum of any attribute's kind
bilalabbad Aug 13, 2024
ee4915b
reset comment form after successful submit
bilalabbad Aug 13, 2024
2d53842
Prepare v0.15.3 Release (#4090)
lykinsbd Aug 13, 2024
f4372c4
chore: update docker-compose
opsmill-bot Aug 13, 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
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ jobs:
uses: DavidAnson/markdownlint-cli2-action@v16
with:
config: .markdownlint.yaml
globs: '**/*.{md,mdx}'
globs: |
**/*.{md,mdx}
!changelog/*.md
!python_sdk/changelog/*.md

action-lint:
if: needs.files-changed.outputs.github_workflows == 'true'
Expand Down Expand Up @@ -512,7 +515,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: screenshots
path: docs/media/*
path: docs/docs/media/*
- name: Upload cypress videos
if: failure()
uses: actions/upload-artifact@v4
Expand Down
10 changes: 0 additions & 10 deletions .github/workflows/release-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,6 @@ jobs:
flavor: |
latest=false

# Commented until we agree to link Infrahub version and chart version
# extract-version:
# runs-on: ubuntu-22.04
# outputs:
# version: ${{ steps.extract_version.outputs.version }}
# steps:
# - name: Extract version from tag
# id: extract_version
# run: echo "version=${GITHUB_REF_NAME/infrahub-v/}" >> $GITHUB_OUTPUT

publish-docker-image:
uses: ./.github/workflows/ci-docker-image.yml
secrets: inherit
Expand Down
12 changes: 0 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@ jobs:
labels: |
org.opencontainers.image.source=${{ github.repository }}

# Commented until we agree to link Infrahub version and chart version
# extract-version:
# runs-on: ubuntu-22.04
# outputs:
# version: ${{ steps.extract_version.outputs.version }}
# steps:
# - name: Extract version from tag
# id: extract_version
# run: echo "version=${GITHUB_REF_NAME/infrahub-v/}" >> $GITHUB_OUTPUT

publish-docker-image:
uses: ./.github/workflows/ci-docker-image.yml
secrets: inherit
Expand All @@ -52,7 +42,5 @@ jobs:
publish-helm-chart:
uses: ./.github/workflows/publish-helm-chart.yml
secrets: inherit
# needs: extract-version
with:
publish: true
# version: ${{ needs.extract-version.outputs.version }}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
# yamllint disable rule:truthy
name: Update Docker Compose on Pyproject update in Stable
name: Update Docker Compose & helm chart on Pyproject update in Stable

# This will bump the infrahub docker image in the docker-compose.yml
# when pyproject.toml is change in the stable branch
Expand Down Expand Up @@ -46,6 +46,8 @@ jobs:
run: "poetry run invoke dev.gen-config-env -u"
- name: "Update Infrahub Image Version in docker-compose.yml file"
run: "poetry run invoke dev.update-docker-compose"
- name: "Update AppVersion in helm/chart.yaml file"
run: "poetry run invoke dev.update-helm-chart"
- name: Commit docker-compose.yml
uses: github-actions-x/[email protected]
with:
Expand Down
19 changes: 10 additions & 9 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
---
default: true
MD013: false # disables max line-length
MD024: false # disables 'no duplicate headings', which we use in tabs for instructions
MD013: false # disables max line-length
MD014: false # dollar signs used before commands
MD024: false # disables 'no duplicate headings', which we use in tabs for instructions
MD025:
front_matter_title: "" # prevent collisions with h1s and frontmatter titles
MD029: false # allows manually creating ordered lists
MD033: false # allows inline html to override markdown styles
MD034: false # no-bare-urls
MD045: false # no alt text around images
MD047: false # single trailing newline
MD014: false # dollar signs used before commands
front_matter_title: "" # prevent collisions with h1s and frontmatter titles
MD029: false # allows manually creating ordered lists
MD033: false # allows inline html to override markdown styles
MD034: false # no-bare-urls
MD041: false # allow 1st line to not be a top-level heading (required for Towncrier)
MD045: false # no alt text around images
MD047: false # single trailing newline
8 changes: 8 additions & 0 deletions .vale/styles/spelling-exceptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ async
boolean
check_definitions
class_name
codespace
codespaces
config
Config
Expand Down Expand Up @@ -54,25 +55,31 @@ IPAM
isort
jinja
Jotai
JSONSchema
kbps
Loopbacks
markdownlint
max_count
memgraph
menu_placement
min_max
modeline
modularization
namespace
namespaces
Nautobot
Netbox
Newsfragment
Nornir
npm
o'brian
openconfig
opentelemetry
PyPI
query_peers
rebase
rebased
Redoc
repo
REST
ressources
Expand All @@ -81,6 +88,7 @@ sdk
subnet
template_path
toml
Towncrier
uncheck
validator
upsert
Expand Down
4 changes: 4 additions & 0 deletions .yamllint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ ignore: |
rules:
new-lines: disable
comments-indentation: disable
comments:
# Changed this to stop a mess between linters from Prettier (vscode) to yamllint
# See https://github.com/prettier/prettier/pull/10926 or https://github.com/redhat-developer/vscode-yaml/issues/433
min-spaces-from-content: 1
line-length:
max: 120
allow-non-breakable-words: true
Expand Down
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Infrahub Changelog

This is the changelog for Infrahub.
All notable changes to this project will be documented in this file.

Issue tracking is located in [Github](https://github.com/opsmill/infrahub/issues).

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the changes for the upcoming release can be found in <https://github.com/opsmill/infrahub/tree/develop/infrahub/changelog/>.

<!-- towncrier release notes start -->

## [0.15.3](https://github.com/opsmill/infrahub/tree/v0.15.3) - 2024-08-13

### Added

- Add usage of Towncrier to generate Changelog as part of the release process.
For detailed information, see the [Documentation](https://docs.infrahub.app/development/changelog). ([#4023](https://github.com/opsmill/infrahub/issues/4023))
- Serve Swagger & Redoc files locally so that the REST-API docs work offline or when isolated from the internet. ([#4063](https://github.com/opsmill/infrahub/issues/4063))

### Fixed

- Fix attribute uniqueness check that was incorrectly running against schema nodes, ([#3986](https://github.com/opsmill/infrahub/issues/3986))
- Provide better information when available during schema conflicts in the pipeline. ([#3987](https://github.com/opsmill/infrahub/issues/3987))
- Fix schema sync issue between worker nodes. ([#3994](https://github.com/opsmill/infrahub/issues/3994))
- Updates the profile type select when creating a profile, to display more relevant information about the related nodes. ([#4001](https://github.com/opsmill/infrahub/issues/4001))
- Fix logic that prevented existing inherited attribute / relationships from being updated. ([#4004](https://github.com/opsmill/infrahub/issues/4004))
- Fix attribute uniqueness validator to not run in isolated mode. ([#4025](https://github.com/opsmill/infrahub/issues/4025))
- Update getting-started/branches referencing the wrong org from previous step.
Update getting-started/resource-manager referencing the wrong button.
Regenerate the screenshots for the tutorial. ([#4035](https://github.com/opsmill/infrahub/issues/4035))
- Fix object creation for schema node using enum attribute in uniqueness constraint groups. ([#4054](https://github.com/opsmill/infrahub/issues/4054))
24 changes: 24 additions & 0 deletions backend/infrahub/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from typing import NoReturn

from fastapi import APIRouter
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
)
from starlette.responses import HTMLResponse

from infrahub.api import (
artifact,
Expand Down Expand Up @@ -30,6 +35,25 @@
router.include_router(transformation.router)


@router.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html() -> HTMLResponse:
return get_swagger_ui_html(
openapi_url="/api/openapi.json",
title="Infrahub - Swagger UI",
swagger_js_url="/api-static/swagger-ui-bundle.js",
swagger_css_url="/api-static/swagger-ui.css",
)


@router.get("/redoc", include_in_schema=False)
async def redoc_html() -> HTMLResponse:
return get_redoc_html(
openapi_url="/api/openapi.json",
title="Infrahub - ReDoc",
redoc_js_url="/api-static/redoc.standalone.js",
)


@router.api_route(
"/{rest_of_path:path}",
methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
Expand Down
1,782 changes: 1,782 additions & 0 deletions backend/infrahub/api/static/redoc.standalone.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions backend/infrahub/api/static/swagger-ui-bundle.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions backend/infrahub/api/static/swagger-ui.css

Large diffs are not rendered by default.

23 changes: 22 additions & 1 deletion backend/infrahub/core/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from infrahub.core.schema import AttributeSchema
from infrahub.database import InfrahubDatabase

# pylint: disable=redefined-builtin,c-extension-no-member
# pylint: disable=redefined-builtin,c-extension-no-member,too-many-public-methods


class AttributeCreateData(BaseModel):
Expand Down Expand Up @@ -238,6 +238,11 @@ def validate_content(cls, value: Any, name: str, schema: AttributeSchema) -> Non
except ValueError as exc:
raise ValidationError({name: f"{value} must be one of {schema.enum!r}"}) from exc

@classmethod
def deserialize_from_string(cls, value_as_string: str) -> Any:
"""Return a value corresponding to the attribute type given it formatted as a string."""
return cls.type(value_as_string) # pylint: disable=not-callable

def to_db(self) -> dict[str, Any]:
"""Return the properties of the AttributeValue node in Dict format."""
data: dict[str, Any] = {"is_default": self.is_default}
Expand Down Expand Up @@ -576,6 +581,10 @@ class AnyAttribute(BaseAttribute):
def validate_format(cls, value: Any, name: str, schema: AttributeSchema) -> None:
pass

@classmethod
def deserialize_from_string(cls, value_as_string: str) -> Any:
return value_as_string


class String(BaseAttribute):
type = str
Expand Down Expand Up @@ -918,6 +927,12 @@ def to_db(self) -> dict[str, Any]:
class ListAttribute(BaseAttribute):
type = list

@classmethod
def deserialize_from_string(cls, value_as_string: str) -> Any:
if value_as_string:
return ujson.loads(value_as_string)
return []

def serialize_value(self) -> str:
"""Serialize the value before storing it in the database."""
return ujson.dumps(self.value)
Expand All @@ -932,6 +947,12 @@ def deserialize_value(self, data: AttributeFromDB) -> Any:
class JSONAttribute(BaseAttribute):
type = (dict, list)

@classmethod
def deserialize_from_string(cls, value_as_string: str) -> Any:
if value_as_string:
return ujson.loads(value_as_string)
return {}

def serialize_value(self) -> str:
"""Serialize the value before storing it in the database."""
return ujson.dumps(self.value)
Expand Down
8 changes: 8 additions & 0 deletions backend/infrahub/core/diff/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ class ObjectConflict(BaseModel):
kind: str
id: str

@property
def label(self) -> str:
return f"{self.name} ({self.id})"

def to_conflict_dict(self) -> dict[str, Any]:
return self.model_dump()

Expand All @@ -270,6 +274,10 @@ class SchemaConflict(ObjectConflict):
branch: str
value: str

@property
def label(self) -> str:
return self.value


class DiffElementType(str, Enum):
ATTRIBUTE = "Attribute"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async def record_conflicts(self, proposed_change_id: str, conflicts: List[Object

await conflict_obj.new(
db=self.db,
label=f"{conflict.name} ({conflict.id})",
label=conflict.label,
origin="internal",
kind="DataIntegrity",
validator=validator.id,
Expand Down
17 changes: 16 additions & 1 deletion backend/infrahub/core/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ async def get_one_by_hfid(
include_owner: bool = False,
prefetch_relationships: bool = False,
account=None,
branch_agnostic: bool = False,
raise_on_error: Literal[False] = False,
) -> Optional[Any]: ...

Expand All @@ -576,6 +577,7 @@ async def get_one_by_hfid(
include_owner: bool = False,
prefetch_relationships: bool = False,
account=None,
branch_agnostic: bool = False,
raise_on_error: Literal[True] = True,
) -> Any: ...

Expand All @@ -592,6 +594,7 @@ async def get_one_by_hfid(
include_owner: bool = False,
prefetch_relationships: bool = False,
account=None,
branch_agnostic: bool = False,
raise_on_error: bool = False,
) -> Optional[Any]:
branch = await registry.get_branch(branch=branch, db=db)
Expand All @@ -603,7 +606,18 @@ async def get_one_by_hfid(
if not node_schema.human_friendly_id or len(node_schema.human_friendly_id) != len(hfid):
raise NodeNotFoundError(branch_name=branch.name, node_type=kind, identifier=hfid_str)

filters = {node_schema.human_friendly_id[idx]: item for idx, item in enumerate(hfid)}
filters = {}
for key, item in zip(node_schema.human_friendly_id, hfid):
path = node_schema.parse_schema_path(path=key, schema=registry.schema.get_schema_branch(name=branch.name))

if path.is_type_relationship:
rel_schema = path.related_schema
# Keep the relationship attribute path and parse it
path = rel_schema.parse_schema_path(
path=key.split("__", maxsplit=1)[1], schema=registry.schema.get_schema_branch(name=branch.name)
)

filters[key] = path.attribute_schema.get_class().deserialize_from_string(item)

items = await NodeManager.query(
db=db,
Expand All @@ -617,6 +631,7 @@ async def get_one_by_hfid(
include_source=include_source,
prefetch_relationships=prefetch_relationships,
account=account,
branch_agnostic=branch_agnostic,
)

if len(items) < 1:
Expand Down
6 changes: 5 additions & 1 deletion backend/infrahub/core/node/constraints/grouped_uniqueness.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ def _build_query_request(
if filters and attribute_path.attribute_schema.name in filters:
include_in_query = True
attribute_name = attribute_path.attribute_schema.name
attribute_value = getattr(updated_node, attribute_name).value
attribute = getattr(updated_node, attribute_name)
if attribute.is_enum:
attribute_value = attribute.value.value
else:
attribute_value = attribute.value
query_attribute_paths.add(
QueryAttributePath(
attribute_name=attribute_name,
Expand Down
Loading
Loading