8000 Add NumberPool Documentation by FragmentedPacket · Pull Request #6577 · opsmill/infrahub · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add NumberPool Documentation #6577

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

Merged
16 changes: 16 additions & 0 deletions docs/_templates/schema/attribute_kind_params.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<!-- vale Infrahub.spelling = NO -->

<Tabs>
{%- for kind, params in kinds.items() | sort %}
<TabItem value="{{ kind }}">
| Parameter | Default |
| --------- | ------- |
{% for name, info in params.items() -%}
| {{ name }} | {{ info.default | default(False) }} |
{% endfor -%}
</TabItem>
{%- endfor %}
</Tabs>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docs/media/schema_numberpool.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions docs/docs/snippets/attribute-kind-params.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<!-- vale Infrahub.spelling = NO -->

<Tabs>
<TabItem value="Number">
| Parameter | Default |
| --------- | ------- |
| min_value | None |
| max_value | None |
| excluded_values | None |
</TabItem>
<TabItem value="NumberPool">
| Parameter | Default |
| --------- | ------- |
| end_range | 9223372036854775807 |
| start_range | 1 |
</TabItem>
<TabItem value="Text">
| Parameter | Default |
| --------- | ------- |
| regex | None |
| min_length | None |
| max_length | None |
</TabItem>
<TabItem value="TextArea">
| Parameter | Default |
| --------- | ------- |
| regex | None |
| min_length | None |
| max_length | None |
</TabItem>
</Tabs>
137 changes: 137 additions & 0 deletions docs/docs/topics/schema-attr-kind-number-pool.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
title: Attribute - NumberPool
---

The `NumberPool` attribute kind enables the dynamic creation of a `CoreNumberPool` for the specific schema node and attribute rather than requiring users to define this after the schema is loaded.

:::info Resource pool initial creation

`NumberPool` kind creates the `CoreNumberPool` resource manager during schema initialization.

:::

## Defining a `NumberPool` attribute {#define-number-pool}

When defining a `NumberPool` attribute, you'll have to define extra `parameters` on the attribute to define the `start_range` and `end_range` for the `CoreNumberPool` resource manager.

We'll define a generic service schema that nodes will inherit from to provide a global service identifier among different schema node services.

```yaml
# yaml-language-server: $schema=https://schema.infrahub.app/infrahub/schema/latest.json
---
version: "1.0"
generics:
- name: Service
namespace: Infra
description: "Services"
default_filter: name__value
order_by:
- name__value
display_labels:
- name__value
attributes:
- name: name
kind: Text
label: Name
optional: false
order_weight: 1
- name: service_identifier
kind: NumberPool
read_only: true # Required
parameters:
start_range: 100
end_range: 10000
nodes:
- name: BackBoneService
namespace: Infra
description: "Backbone Service"
label: "Backbone Service"
icon: "carbon:container-services"
inherit_from:
- InfraService
uniqueness_constraints:
- ["circuit_id__value", "internal_circuit_id__value"]
attributes:
- name: circuit_id
kind: Text
label: Circuit ID
optional: false
order_weight: 3
- name: internal_circuit_id
kind: Text
label: Internal Circuit ID
optional: false
order_weight: 2
relationships:
- name: provider
cardinality: one
peer: OrganizationProvider
optional: false
kind: Attribute
- name: site_a
label: Site A
cardinality: one
peer: LocationSite
optional: false
identifier: infrabackboneservice__location_site_a
kind: Attribute
order_weight: 4
- name: site_b
label: Site B
cardinality: one
peer: LocationSite
optional: false
identifier: infrabackboneservice__location_site_b
kind: Attribute
order_weight: 5
```

We can view the schema in the **Schema Visualizer**.

![numberpool-schema](../media/schema_numberpool.png)

## Viewing the Resource Manager

Once we create an initial `InfraBackBoneService`, we can navigate to the resource manager page and view the details of the created resource manager.

The naming of the resource manager will be `Kind.attribute_name [uuid]`.

![numberpool-resource-manager](../media/numberpool_attribute_kind_resource_manager.png)

:::info Updating Parameters (Start/End Range)

To update the **parameters** of a `NumberPool` attribute requires performing a schema update.

:::

## Deleting the Resource Manager

To remove the resource manager, the attribute must be removed by defining `state: absent` on the attribute in the schema. The resource manager will then be removed during the schema loading.

```yaml
# yaml-language-server: $schema=https://schema.infrahub.app/infrahub/schema/latest.json
---
version: "1.0"
generics:
- name: Service
namespace: Infra
description: "Services"
default_filter: name__value
order_by:
- name__value
display_labels:
- name__value
attributes:
- name: name
kind: Text
label: Name
optional: false
order_weight: 1
- name: service_identifier
state: absent
kind: NumberPool
read_only: true # Required
parameters:
start_range: 100
end_range: 10000
```
11 changes: 10 additions & 1 deletion docs/docs/topics/schema.mdx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
---
title: Schema
title: Overview
---

import VideoPlayer from '../../src/components/VideoPlayer';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import ReferenceLink from "../../src/components/Card";
import SnippetAttributeKindParams from "../snippets/attribute-kind-params.mdx"

# Schema

Expand Down Expand Up @@ -108,6 +109,7 @@ The `kind` of a model is generated by concatenating the `namespace` and the `nam

* `Text`: Standard Text
* `Number`: Standard Number
* `NumberPool`: Standard Number that creates a `CoreNumberPool` resource manager tied to the attribute
* `TextArea`: Long-form Text that can span multiple lines
* `DateTime`: A Date and a Time
* `Dropdown`: A list of choices, each choice can have a color and description
Expand Down Expand Up @@ -135,6 +137,7 @@ The `kind` of a model is generated by concatenating the `namespace` and the `nam
| `ID` | No | Yes |
| `Text` | Yes | Yes |
| `Number` | Yes | Yes |
| `NumberPool` | Yes | Yes |
| `Boolean` | Yes | Yes |
| `Dropdown` | Yes | Yes |
| `TextArea` | No | Yes |
Expand All @@ -155,6 +158,12 @@ The `kind` of a model is generated by concatenating the `namespace` and the `nam

</details>

#### Attribute Parameters

There are some attribute kinds that allow optional `parameters` to be defined to control the behavior of the attribute. Below are the attribute kinds and their accepted parameters.

<SnippetAttributeKindParams />

#### Relationship kinds

* `Generic`: A flexible relationship with no specific functional significance. It is commonly used when an entity doesn't fit into specialized categories like `Component` or `Parent`.
Expand Down
9 changes: 8 additions & 1 deletion docs/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,14 @@ const sidebars: SidebarsConfig = {
'topics/repository',
'topics/resource-manager',
'topics/resources-testing-framework',
'topics/schema',
{
type: 'category',
label: 'Schema',
items: [
'topics/schema',
'topics/schema-attr-kind-number-pool',
],
},
'topics/tasks',
'topics/transformation',
'topics/version-control',
Expand Down
9 changes: 9 additions & 0 deletions frontend/app/tests/e2e/resource-manager/number-pool.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, test } from "@playwright/test";
import { ACCOUNT_STATE_PATH } from "../../constants";
import { saveScreenshotForDocs } from "../../utils";

test.describe("/resource-manager - Resource Manager", () => {
test.describe.configure({ mode: "serial" });
Expand Down Expand Up @@ -42,4 +43,12 @@ test.describe("/resource-manager - Resource Manager", () => {
await expect(page.getByText("Node *")).not.toBeVisible();
await expect(page.getByText("Attribute *")).not.toBeVisible();
});

test("numberpool attribute kind resource manager", async ({ page }) => {
await page.goto("/resource-manager");
await expect(page.getByRole("link", { name: "InfraService." })).toBeVisible();
await page.getByRole("link", { name: "InfraService." }).click();
await page.getByRole("link", { name: "View", exact: true }).click();
await saveScreenshotForDocs(page, "numberpool_attribute_kind_resource_manager");
});
});
11 changes: 11 additions & 0 deletions frontend/app/tests/e2e/schema.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect, test } from "@playwright/test";
import { saveScreenshotForDocs } from "../utils";

test.describe("/schema - Schema visualizer", () => {
test("display help menu correctly", async ({ page }) => {
Expand Down Expand Up @@ -48,4 +49,14 @@ test.describe("/schema - Schema visualizer", () => {
await expect(page.getByRole("heading", { name: "Builtin Tag Node" })).toBeVisible();
await expect(page.getByRole("heading", { name: "Core Account Node" })).not.toBeVisible();
});

test("view schema attribute kind numberpool", async ({ page }) => {
await page.goto("/schema");
await page.getByPlaceholder("Search schema").fill("InfraBackBoneService");
await page.getByText("InfraBackbone Service").click();
await page.getByRole("tab", { name: "Attributes" }).click();
await page.getByText("Service Identifier NumberPool").click();
await page.getByText("Parameters").click();
await saveScreenshotForDocs(page, "schema_numberpool");
});
});
6 changes: 6 additions & 0 deletions models/base/service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ generics:
label: Name
optional: false
order_weight: 1
- name: service_identifier
kind: NumberPool
read_only: true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR but I think we shouldn't require the user to define read_only: true for NumberPool and Computed Attribute, it should be automatic and we should raise an error if user is trying to enforce read_only: false
cc @ogenstad @wvandeun

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now as the read_only attribute defaults to False in the models I'm not sure we can do that. If we look at models for the schema generation we could change it so that it would default to None and get changed to False if no choice has been made.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree that it would be nice to have this type of attribute (and computed attribtute) to be read-only by default.
If it is not possible to do it today, or if it is to involved the we should open an issue/feature request in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be part of INFP-234 where we somewhere add a note that we want this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the information as a comment on it

parameters:
start_range: 100
end_range: 10000
nodes:
- name: BackBoneService
namespace: Infra
Expand Down
10 changes: 10 additions & 0 deletions models/infrastructure_edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,16 @@ async def create_backbone_connectivity(
f"Backbone: Connected to {backbone_link.site1_device} via {backbone_link.circuit}"
)
await intf_site2_obj.save()
bb_service = await client.create(
kind="InfraBackBoneService",
name=f"BKB: {backbone_link.site1} <-> {backbone_link.site2}",
circuit_id=backbone_link.circuit,
internal_circuit_id=vendor_id.upper(),
provider=provider,
site_a=backbone_link.site1,
site_b=backbone_link.site2,
)
await bb_service.save(allow_upsert=True)

log.debug(
f" - Connected '{backbone_link.site1_device}::{intf_site1.name.value}' <> '{backbone_link.site2_device}::{intf_site2.name.value}'"
Expand Down
38 changes: 38 additions & 0 deletions tasks/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def generate(context: Context) -> None:
def generate_schema(context: Context) -> None: # noqa: ARG001
"""Generate documentation for the schema."""
_generate_infrahub_schema_documentation()
_generate_infrahub_schema_attribute_kind_parameters_snippet()


@task
Expand Down Expand Up @@ -191,11 +192,48 @@ def _generate(context: Context) -> None:
# with context.cd(ESCAPED_REPO_PATH):
# context.run(exec_cmd)


# for cmd in app.registered_groups:
# exec_cmd = f"poetry run typer infrahub_sdk.ctl.{cmd.name} utils docs"
# exec_cmd += f' --name "infrahubctl {cmd.name}" --output docs/docs/infrahubctl/infrahubctl-{cmd.name}.mdx'
# with context.cd(ESCAPED_REPO_PATH):
# context.run(exec_cmd)
def _generate_infrahub_schema_attribute_kind_parameters_snippet() -> None:
"""Generate documentation for any attributes that have parameters defined to be defined by users."""
import jinja2

from infrahub.core.schema.attribute_schema import attribute_schema_class_by_kind

kind_ap_parameters: dict[str, dict] = {}
for kind, schema_cls in attribute_schema_class_by_kind.items():
# If the schema has a parameters class, add it to the list
init_schema = schema_cls(name="ignore", kind=kind)
if hasattr(init_schema, "parameters") and init_schema.parameters is not None:
params = {
param: info
for param, info in init_schema.parameters.model_fields.items()
if info.json_schema_extra and info.json_schema_extra.get("update") == "validate_constraint"
}
kind_ap_parameters[kind] = params
# for _, obj in inspect.getmembers(ap):
# if inspect.isclass(obj) and issubclass(obj, ap.AttributeParameters) and obj is not ap.AttributeParameters:
# kind_ap_parameters.append(obj)

template_file = Path(DOCUMENTATION_DIRECTORY) / "_templates" / "schema" / "attribute_kind_params.j2"
output_file = Path(DOCUMENTATION_DIRECTORY) / "docs" / "snippets" / "attribute-kind-params.mdx"
output_label = "docs/docs/snippets/attribute-kind-params.mdx"
if not template_file.exists():
print(f"Unable to find the template file at {template_file}")
sys.exit(-1)

template_text = template_file.read_text(encoding="utf-8")

environment = jinja2.Environment()
template = environment.from_string(template_text)
rendered_file = template.render(kinds=kind_ap_parameters)

output_file.write_text(rendered_file, encoding="utf-8")
print(f"Docs saved to: {output_label}")


def _generate_infrahub_schema_documentation() -> None:
Expand Down
Loading
0