Skip to content

Commit b18c2e4

Browse files
author
github-actions
committed
Sync docs from infrahub-demo-service-catalog repo
1 parent b546e1b commit b18c2e4

File tree

3 files changed

+676
-72
lines changed

3 files changed

+676
-72
lines changed

docs/docs-service-catalog/getting-started/developer-walkthrough.mdx

Lines changed: 233 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,104 @@ In this walkthrough, we detail the key building blocks of the demo, explain how
1212

1313
To structure and store data, we define a schema in Infrahub. You can find the schema files in the `schemas` folder.
1414

15+
### Schema architecture overview
16+
17+
The following diagram illustrates the complete schema architecture, showing how different objects relate to each other in the Service Catalog demo:
18+
19+
```mermaid
20+
graph TB
21+
%% Style definitions
22+
classDef service fill:#e6f3ff,stroke:#4a90e2,stroke-width:3px
23+
classDef dcim fill:#fff2e6,stroke:#ff9800,stroke-width:2px
24+
classDef ipam fill:#e6ffe6,stroke:#4caf50,stroke-width:2px
25+
classDef location fill:#ffe6f2,stroke:#e91e63,stroke-width:2px
26+
classDef generic fill:#f0f0f0,stroke:#666,stroke-width:2px,stroke-dasharray: 5 5
27+
28+
%% Service Layer
29+
ServiceGeneric["Service Generic (Generic)"]:::generic
30+
ServiceDedicatedInternet["Service Dedicated Internet<br/>- status<br/>- bandwidth<br/>- ip_package"]:::service
31+
32+
%% Location Layer
33+
LocationGeneric["Location Generic (Generic)"]:::generic
34+
LocationHosting["Location Hosting (Generic)"]:::generic
35+
LocationSite["Location Site (Concrete)"]:::location
36+
37+
%% DCIM Layer
38+
DcimGenericDevice["Dcim Generic Device (Generic)"]:::generic
39+
DcimPhysicalDevice["Dcim Physical Device (Generic)"]:::generic
40+
DcimDevice["Dcim Device (Concrete)"]:::dcim
41+
DcimInterface["Dcim Interface (Generic)"]:::generic
42+
DcimInterfaceL2["Dcim Interface L2 (Concrete)"]:::dcim
43+
DcimInterfaceL3["Dcim Interface L3 (Concrete)"]:::dcim
44+
45+
%% IPAM Layer
46+
IpamIPAddress["Ipam IP Address"]:::ipam
47+
IpamPrefix["Ipam Prefix<br/>- status<br/>- role"]:::ipam
48+
IpamVLAN["Ipam VLAN<br/>- vlan_id<br/>- status<br/>- role"]:::ipam
49+
IpamL2Domain["Ipam L2 Domain"]:::ipam
50+
51+
%% Inheritance relationships
52+
ServiceGeneric -.->|inherits| ServiceDedicatedInternet
53+
LocationGeneric -.->|inherits| LocationHosting
54+
LocationHosting -.->|inherits| LocationSite
55+
DcimGenericDevice -.->|inherits| DcimPhysicalDevice
56+
DcimPhysicalDevice -.->|inherits| DcimDevice
57+
DcimInterface -.->|inherits| DcimInterfaceL2
58+
DcimInterface -.->|inherits| DcimInterfaceL3
59+
60+
%% Service Relationships
61+
ServiceDedicatedInternet -->|"location (1:1)"| LocationSite
62+
ServiceDedicatedInternet -->|"dedicated_interfaces (1:many)"| DcimInterface
63+
ServiceDedicatedInternet -->|"vlan (1:1)"| IpamVLAN
64+
ServiceDedicatedInternet -->|"gateway_ip_address (1:1)"| IpamIPAddress
65+
ServiceDedicatedInternet -->|"prefix (1:1)"| IpamPrefix
66+
67+
%% Location Relationships
68+
LocationSite -->|"services (1:many)"| ServiceGeneric
69+
LocationHosting -->|"devices (1:many)"| DcimPhysicalDevice
70+
LocationHosting -->|"prefixes (1:many)"| IpamPrefix
71+
LocationHosting -->|"vlans (1:many)"| IpamVLAN
72+
73+
%% Device Relationships
74+
DcimDevice -->|"location (1:1)"| LocationHosting
75+
DcimGenericDevice -->|"interfaces (1:many)"| DcimInterface
76+
DcimGenericDevice -->|"primary_address (1:1)"| IpamIPAddress
77+
78+
%% Interface Relationships
79+
DcimInterfaceL2 -->|"untagged_vlan (1:1)"| IpamVLAN
80+
DcimInterfaceL2 -->|"tagged_vlan (1:many)"| IpamVLAN
81+
DcimInterfaceL3 -->|"ip_addresses (1:many)"| IpamIPAddress
82+
83+
%% IPAM Relationships
84+
IpamIPAddress -->|"interface (1:1)"| DcimInterfaceL3
85+
IpamPrefix -->|"vlan (1:1)"| IpamVLAN
86+
IpamVLAN -->|"l2domain (1:1)"| IpamL2Domain
87+
IpamL2Domain -->|"vlans (1:many)"| IpamVLAN
88+
89+
%% Highlight key service flow
90+
ServiceDedicatedInternet -.->|"allocates from pool"| IpamVLAN
91+
ServiceDedicatedInternet -.->|"allocates from pool"| IpamPrefix
92+
ServiceDedicatedInternet -.->|"finds available"| DcimInterface
93+
ServiceDedicatedInternet -.->|"creates gateway"| IpamIPAddress
94+
```
95+
96+
#### Key concepts in the diagram
97+
98+
1. **Generic vs Concrete Objects**:
99+
- **Generic** (dashed boxes): Abstract base classes that define common attributes
100+
- **Concrete** (solid boxes): Actual objects that can be instantiated
101+
102+
2. **Object Categories**:
103+
- **Service Layer** (blue): Service definitions and instances
104+
- **Location Layer** (pink): Geographic hierarchy and hosting locations
105+
- **DCIM Layer** (orange): Physical devices and interfaces
106+
- **IPAM Layer** (green): Network resources (IPs, VLANs, prefixes)
107+
108+
3. **Relationship Types**:
109+
- **Inheritance** (dashed arrows): Shows class hierarchy
110+
- **Associations** (solid arrows): Shows data relationships with cardinality
111+
- **Resource Allocation** (dotted arrows): Shows dynamic provisioning flow
112+
15113
### Consuming the schema library
16114

17115
Much of the schema is based on the [Infrahub schema library](https://github.com/opsmill/schema-library), which provides reusable schema components for quickly scaffolding a schema.
@@ -240,6 +338,7 @@ The generator is a powerful feature of Infrahub that allows you to codify the ru
240338
We want to build the generator with the concept of **idempotency** in mind, meaning it should be repeatable: it assigns resources the first time it runs, and if run again, it changes nothing if the desired state is already achieved. This approach ensures the code is robust and predictable.
241339
242340
Infrahub provides a set of features to help:
341+
243342
- Resource manager: It allows users to create pools and allocate resources from them, such as prefixes, IP addresses, or even numbers. We will use this feature to allocate our prefixes/vlan in a branch-agnostic and idempotent way. Learn more about [resource managers](https://docs.infrahub.app/topics/resource-manager).
244343
- `allow_upsert=True`: This parameter is provided when saving the node, allowing it to be created if it doesn't exist or updated if it does. This is useful for ensuring that the generator can run multiple times without creating duplicates or errors.
245344

@@ -502,10 +601,141 @@ class DedicatedInternetGenerator(InfrahubGenerator):
502601

503602
```
504603

505-
:::success
604+
### Generator architecture patterns
605+
606+
1. **Resource Tracking**: Every allocation linked to the service
607+
2. **Relationship Integrity**: Bi-directional references maintained
608+
3. **Error Handling**: Fail fast with clear messages
609+
4. **Logging**: Detailed progress tracking for troubleshooting
610+
611+
### Service provisioning flow
612+
613+
Here's a focused view of how resources flow during service provisioning:
614+
615+
```mermaid
616+
flowchart LR
617+
%% Style definitions
618+
classDef request fill:#ffd700,stroke:#333,stroke-width:2px
619+
classDef pool fill:#87ceeb,stroke:#333,stroke-width:2px
620+
classDef resource fill:#98fb98,stroke:#333,stroke-width:2px
621+
classDef service fill:#ffb6c1,stroke:#333,stroke-width:2px
622+
623+
%% Nodes
624+
SR[Service Request]:::request
625+
SP[Service Object]:::service
626+
627+
VP["VLAN Pool<br/>100-199"]:::pool
628+
PP["Prefix Pool<br/>10.0.0.0/16"]:::pool
629+
630+
V[VLAN 142]:::resource
631+
P["Prefix 10.0.42.0/28"]:::resource
632+
SW["Switch Port<br/>ge-0/0/5"]:::resource
633+
GW["Gateway IP<br/>10.0.42.1/28"]:::resource
634+
635+
%% Flow
636+
SR -->|Creates| SP
637+
SP -->|"Allocates from"| VP
638+
SP -->|"Allocates from"| PP
639+
VP -->|Provides| V
640+
PP -->|Provides| P
641+
SP -->|"Finds available"| SW
642+
P -->|"First IP becomes"| GW
643+
644+
%% Assignments
645+
V -.->|"Assigned to"| SP
646+
P -.->|"Assigned to"| SP
647+
SW -.->|"Assigned to"| SP
648+
GW -.->|"Assigned to"| SP
649+
```
506650

507-
At this stage, we have a generator that transforms a high-level service request into a complete service, sourcing resources from predefined pools with consistency and in just seconds.
651+
### Summary: From request to reality
508652

509-
:::
653+
The generator transforms a service request:
654+
655+
```yaml
656+
Service: DI-12345
657+
Location: Atlanta
658+
Bandwidth: 1 Gbps
659+
IP Package: Medium
660+
```
661+
662+
Into fully provisioned infrastructure:
663+
664+
- VLAN 142 allocated and configured
665+
- IP prefix 10.0.42.0/28 assigned
666+
- Switch port ge-0/0/5 configured
667+
- Router interface vlan_142 with IP 10.0.42.1/28
668+
669+
All in seconds, consistently, and idempotently!
510670
511671
<ReferenceLink title="Learn about Infrahub generators" url="https://docs.infrahub.app/topics/generator" openInNewTab/>
672+
673+
## The service portal architecture
674+
675+
### Streamlit for the user interface
676+
677+
The demo uses [Streamlit](https://streamlit.io/) for the user interface because it:
678+
679+
- Builds web UIs with pure Python (no JavaScript required)
680+
- Provides ready-made components for forms and data display
681+
- Integrates seamlessly with the Infrahub Python SDK
682+
- Enables rapid prototyping of service catalogs
683+
684+
### Portal design patterns
685+
686+
#### Infrahub SDK integration
687+
688+
The portal uses several patterns to efficiently interact with Infrahub:
689+
690+
```python title="Client Caching Pattern"
691+
@st.cache_resource
692+
def get_client(branch: str = "main") -> InfrahubClientSync:
693+
"""Create and cache Infrahub client."""
694+
address = get_instance_address()
695+
return InfrahubClientSync(
696+
address=address,
697+
config=Config(default_branch=branch)
698+
)
699+
```
700+
701+
:::tip Why Cache the Client?
702+
The `@st.cache_resource` decorator:
703+
704+
- Creates client once and reuses it
705+
- Reduces connection overhead
706+
- Maintains consistent state
707+
- Improves page load performance
708+
:::
709+
710+
<ReferenceLink title="Learn about Streamlit" url="https://streamlit.io/" openInNewTab/>
711+
712+
## Architecture takeaways
713+
714+
### Key design decisions
715+
716+
1. **Schema as Foundation**: Well-designed schema enables everything else
717+
2. **Automation through Generators**: Complex provisioning made straightforward
718+
3. **Resource Management**: Centralized pools prevent conflicts
719+
4. **Branch-Based Workflows**: Safe testing and rollback capabilities
720+
5. **User-Friendly Abstractions**: Hide complexity behind clear choices
721+
722+
### Extending the demo
723+
724+
Consider these enhancements for production use:
725+
726+
- Additional service types (MPLS, Cloud Connect, etc.)
727+
- Approval workflows with human checkpoints
728+
- Integration with ITSM platforms
729+
- Automated testing of provisioned services
730+
- Rollback and decommissioning automation
731+
732+
## Next steps
733+
734+
Now that you understand the architecture:
735+
736+
1. **Run the Demo**: Follow the [installation guide](installation) to set up locally
737+
2. **Try the Portal**: Walk through the [user experience](user-walkthrough)
738+
3. **Explore Further**: Modify the schema or create new service types
739+
4. **Build Your Own**: Apply these patterns to your infrastructure needs
740+
741+
The combination of Infrahub's flexible schema, powerful generators, and Python-based portals enables you to build sophisticated service automation tailored to your organization's needs.

0 commit comments

Comments
 (0)