Change Instance Generation Logic
When a new consumer submits a declaration, it may lead to the creation of change instances for the service items. These change instances are sent to the service owners, who then process them in the consumer's infrastructure. Understanding how these change instances are generated is crucial.
There are 3 types of changes instances:
change_type | Description Summary |
---|---|
CREATE |
A new service item is requested. |
MODIFY |
An existing service item is requested to be modified. |
DELETE |
A request to delete an existing service item. |
Basic Submissions
In this page, several examples of submissions are provided.
Before a consumer can submit a declaration, the relevant services must be defined in NetOrca.
For simplicity, let's assume there are two services, VM
managed by VMOwnerTeam
and LoadBalancer
managed by LBOwnerTeam
with the following schemas:
CREATE Change Instance
When the consumer submits a declaration including a service item which doesn't exist in NetOrca, a CREATE
change instance for that service item will be generated.
- For example, if a new consumer team submits an initial declaration, since they don't yet have any service items, a
CREATE
change instance will be generated for each service item in the submission:
{
"AwesomeConsumer": {
"NewApp1": {
"services": {
"VM": [{
"name": "CoreVM1",
"cpu": 8,
"memory": 2
}, {
"name": "CoreVM2",
"cpu": 16,
"memory": 4
}]
}
}
}
}
The above declaration will generate two CREATE
change instances for the AwesomeConsumer
team, which will be received by VMOwnerTeam
:
Service Item | change_type | Consumer Team | Service Owner Team |
---|---|---|---|
CoreVM1 |
CREATE |
AwesomeConsumer |
VMOwnerTeam |
CoreVM2 |
CREATE |
AwesomeConsumer |
VMOwnerTeam |
If an existing consumer decides to add new service items to their current resources,
they can submit an updated declaration that includes both the existing and new service items.
For example, if AwesomeConsumer
wants to add a new LoadBalancer
for their existing vms, the new submission would be:
{
"AwesomeConsumer": {
"NewApp1": {
"services": {
"VM": [
{
"name": "CoreVM1",
"cpu": 8,
"memory": 2
},
{
"name": "CoreVM2",
"cpu": 16,
"memory": 4
}
],
"LoadBalancer": [
{
"name": "CoreLB1",
"algorithm": "RoundRobin"
}
]
}
}
}
}
This submission will generate a single CREATE
change instance for LBOwnerTeam
:
Service Item | change_type | Consumer Team | Service Owner Team |
---|---|---|---|
CoreLB1 |
CREATE |
AwesomeConsumer |
LBOwnerTeam |
MODIFY Change Instance
When a consumer submits a request to modify an existing service item's declaration, a MODIFY
change instance is generated.
- For instance, if the
AwesomeConsumer
team decides to upgrade the cpu and memory of an existingVM
, they would submit a declaration with the modified key values of the service item dictionary:
{
"AwesomeConsumer": {
"NewApp1": {
"services": {
"VM": [
{
"name": "CoreVM1",
"cpu": 16, // modified
"memory": 8 // modified
},
{
"name": "CoreVM2",
"cpu": 16,
"memory": 4
}
],
"LoadBalancer": [
{
"name": "CoreLB1",
"algorithm": "RoundRobin"
}
]
}
}
}
}
This submission will generate a MODIFY
change instance for VMOwnerTeam
to process the requested upgrade:
Service Item | change_type | Consumer Team | Service Owner Team |
---|---|---|---|
CoreVM1 |
MODIFY |
AwesomeConsumer |
VMOwnerTeam |
- If the consumer wishes to modify multiple service items, they can include all changes in a single submission. For example, if
AwesomeConsumer
wants to change the algorithm of an existing LoadBalancer and upgrade the other VM, they would submit the following:
{
"AwesomeConsumer": {
"NewApp1": {
"services": {
"VM": [
{
"name": "CoreVM1",
"cpu": 16,
"memory": 8
},
{
"name": "CoreVM2",
"cpu": 8, // modified
"memory": 16 // modified
}
],
"LoadBalancer": [
{
"name": "CoreLB1",
"algorithm": "LeastConnections" // modified
}
]
}
}
}
}
This submission will generate one MODIFY
change instance for LBOwnerTeam
, and one for VMOwnerTeam
:
Service Item | change_type | Consumer Team | Service Owner Team |
---|---|---|---|
CoreVM2 |
MODIFY |
AwesomeConsumer |
VMOwnerTeam |
CoreLB1 |
MODIFY |
AwesomeConsumer |
LBOwnerTeam |
DELETE Change Instance
When a consumer removes the declaration of an existing service item in the next submission, a DELETE
change instance is generated.
- In our example, if
AwesomeConsumer
team decides to remove the load balancer and one of the vms, they would submit a declaration like this:
{
"AwesomeConsumer": {
"NewApp1": {
"services": {
"VM": [
{
"name": "CoreVM1",
"cpu": 16,
"memory": 8
}
]
}
}
}
}
This declaration will generate two DELETE
change instances:
Service Item | change_type | Consumer Team | Service Owner Team |
---|---|---|---|
CoreVM2 |
DELETE |
AwesomeConsumer |
VMOwnerTeam |
CoreLB1 |
DELETE |
AwesomeConsumer |
LBOwnerTeam |
Declarative Submissions
In NetOrca, declarations must be declarative rather than imperative. This distinction is crucial for understanding how change instances are generated.
Declarative declarations focus on what the end state of an application should be. The consumer provides a desired configuration, and NetOrca automatically determines the steps needed to achieve that state. The emphasis is on describing the final outcome. Consumer does not need to care HOW to reach a desired state.
In the first example of CREATE Change Instance section, the consumer team AwesomeConsumer
simply declares that CoreVM1
and CoreVM2
should exist in the system.
Based on this, NetOrca generates 2 CREATE
change instances to provision those VMs.
In the next submission, while the two VMs exist in the submission, the consumer adds a new LoadBalancer service item to the declaration, and submits all at together.
This time, NetOrca detects that the VMs already exist, and so, there should be no CREATE
change instances for VMs.
However, a new load balancer service item is detected. So, only this new service item needs a CREATE
change instance.
Similarly, in MODIFY Change Instance, the consumer updates the cpu and memory of CoreVM1
. However, all service items, including the other existing unchanged VM and the LoadBalancer, are submitted at once.
Therefore, NetOrca detects the new state only for CoreVM1
while the rest remained unchanged.
With declarative approach, consumers only declare the final desired applications, NetOrca detects the changes, and service owners perform the necessary operations behind the scenes based on the generated change instances.
Change Instance Attributes
A Change Instance object includes the following key attributes:
attributes | Description |
---|---|
id |
The unique identifier of a change instance in NetOrca |
state |
Current state of the change instance.(More detail) |
created |
The timestamp when the change instance was generated |
modified |
The timestamp when the change instance was processed |
owner |
The service owner responsible for the change instance |
service_item |
The service item related to the change instance |
new_declaration |
The new declaration for which the change instance was generated |
submission |
The consumer's submission that triggered the generation of the change instance |
log |
A short message provided by Service Owner for the current state of the change instance |
change_type |
The type of change (as described above) |
Referenced Change Instances
Service item references are detailed in Service Definition. This section will focus on the logic behind generating change instances due to references.
Service Schema with References
To demonstrate this, we, first, need to update the service schemas to include references.
A list of references will be added to the LoadBalancer
service schema:
VM:
name: str
cpu: int
ram: int
LoadBalancer:
name: str
related_vms: [array of related vms]
algorithm: str
To prevent confusion with the previously mentioned consumer submissions, a new consumer, AwesomeConsumer2
, will be created, starting with no service items or applications.
In the following example, CoreLB1
will be referred to as the main service item, while CoreVM1
and CoreVM2
will called referenced service items.
When the consumer submits their declaration, change instances will be generated for any modifications, as outlined in Basic Submission section. Additionally, there is potential for extra change instances to be generated, which will be referred to as referenced change instances.
Basic Change Instances
The consumer submits the initial declaration including the load balancer with the name of the VM service items as value for related_vms
field:
{
"AwesomeConsumer2": {
"NewApp1": {
"services": {
"VM": [
{
"name": "CoreVM1",
"cpu": 16,
"memory": 8
},
{
"name": "CoreVM2",
"cpu": 8,
"memory": 16
}
],
"LoadBalancer": [
{
"name": "CoreLB1",
"related_vms": ["CoreVM1", "CoreVM2"],
"algorithm": "LeastConnections"
}
]
}
}
}
}
In the declaration above, "related_vms": ["CoreVM1", "CoreVM2"]
is a new key value which contains the name of vms related to CoreLB1
service item.
Exactly the same as the submissions with no references, the initial submission will generate 3 CREAtE
change instances:
Service Item | change_type | Consumer Team | Service Owner Team |
---|---|---|---|
CoreVM1 |
CREATE |
AwesomeConsumer2 |
VMOwnerTeam |
CoreVM2 |
CREATE |
AwesomeConsumer2 |
VMOwnerTeam |
CoreLB1 |
CREATE |
AwesomeConsumer2 |
LBOwnerTeam |
Referenced Change Instances
In the consumer's submission, if the following conditions are met:
- Both the main and referenced service items already exist,
- The main service item remains unchanged in its declaration, meaning no
MODIFY
change instance would typically be generated, - A modification is made to the declaration of a referenced service item, such as altering one of the VMs,
The main service item, like CoreLB1
, will receive an additional MODIFY
change instance.
In the next submission of the example consumer, if there is modifications in CoreVM1
, not only CoreVM1
will get a MODIFY
change instance, but also, CoreLB1
will get a MODIFY
change instance:
{
"AwesomeConsumer2": {
"NewApp1": {
"services": {
"VM": [
{
"name": "CoreVM1",
"cpu": 16,
"memory": 16 // modified
},
{
"name": "CoreVM2",
"cpu": 8,
"memory": 16
}
],
"LoadBalancer": [
{
"name": "CoreLB1",
"related_vms": ["CoreVM1", "CoreVM2"],
"algorithm": "LeastConnections"
}
]
}
}
}
}
The list of change instances to be generated is:
Service Item | change_type | Consumer Team | Service Owner Team |
---|---|---|---|
CoreVM1 |
MODIFY |
AwesomeConsumer2 |
VMOwnerTeam |
CoreLB1 |
MODIFY |
AwesomeConsumer2 |
LBOwnerTeam |
Note: If both VMs are modified, the load balancer still will get only one MODIFY
referenced change instance.
Important Note: Keep in mind that when a referenced service item is created or removed, the consumer must also update the declaration of the main service item.
For instance, if CoreVM2
is deleted in the next submission, it should be removed from the related_vms
field in CoreLB1
, resulting in "related_vms": ["CoreVM1"]
.
Consequently, CoreLB1
will receive a MODIFY
change instance due to this direct modification in its own declaration, and so, no additional referenced MODIFY
change instance will be generated.
Dependent Change Instances
Dependent Teams are described in detail in Service Definition.
When a consumer's submission generates a change instance for a service that has dependent teams, each dependent team will also receive an additional change instance.
As previously noted, a change instance object includes:
owner
: The individual or Team that processes for the change instance.service_owner_team
: The Owner of its Service Item's Service.consumer_team
: The team that owns the application associated with the service item.
For a basic change instance, the owner
and service_owner_team
are the same.
However, for a dependent change instance, the owner
differs from the service_owner_team
.
In the first example of this page, if the LoadBalancer
team has dependent team, e.g. such as NPOwnerTeam
. The list of change instances will be:
Service Item | change_type | Owner | Consumer Team | Service Owner Team |
---|---|---|---|---|
CoreVM1 |
CREATE |
VMOwnerTeam |
AwesomeConsumer |
VMOwnerTeam |
CoreVM1 |
CREATE |
NPOwnerTeam |
AwesomeConsumer |
VMOwnerTeam |
CoreVM2 |
CREATE |
VMOwnerTeam |
AwesomeConsumer |
VMOwnerTeam |
CoreVM2 |
CREATE |
NPOwnerTeam |
AwesomeConsumer |
VMOwnerTeam |
Change Instance State
The service owners process the change instances and then, they will update the state of each change instance. Here is the table of possible states and their meanings:
state | Description |
---|---|
PENDING |
The change instance is awaiting to be approved and processed |
REJECTED |
The change instance is not valid to be processed |
APPROVED |
The change instance is approved and being processed |
ERRORED |
The change instance is approved but failed during execution |
COMPLETED |
The change instance is processed and finished successfully |
CLOSED |
The change instance is not processed due to an error or rejection |
graph LR
1[PENDING] --> 2[APPROVED]
1 --> 3([REJECTED])
2 --> 4[COMPLETED]
2 --> 5([ERRORED])
3 --> 6([CLOSED])
5 --> 6([CLOSED])
Stack Rules
Once Change Instances are generated from Consumer's Submission, Service Owners begin processing change requests individually. However, since processing might take time and consumers can submit requests at any time, new Change Instances may be created while previous ones are still being processed. In NetOrca, these overlapping Change Instances are referred to as Stacked Change Instances. To manage them effectively, NetOrca enforces specific rules.
A Change Instance goes through three stages in its lifecycle:
Pre-Validated | Validated | Resolved |
---|---|---|
PENDING ,REJECTED |
APPROVED , ERRORED |
COMPLETED ,CLOSED |
Only one change instance per Service Item can remain open in each of these columns; all others will be CLOSED
.
In other words, if an existing change instance is still open (i.e., not COMPLETED
or CLOSED
) and a new change instance comes in—whether through a new submission or as a result of processing by a Service Owner—within the same state column, the previous change instance will be CLOSED
.
This mechanism ensures that only one active change instance per Service Item exists in each stage, preventing conflicts and maintaining consistency in the change management process.
Example 1: Pre-Validated Stage Conflict
- A user submits a change request for a Service Item, which creates Change Instance A in the
PENDING
state (Pre-Validated stage). - Before Change Instance A is processed, the same user submits another request for the same Service Item, creating Change Instance B, also in
PENDING
. - Since both instances belong to the Pre-Validated stage, Change Instance A will be automatically
CLOSED
when Change Instance B is created.
Example 2: Transition to Validated Stage
- Change Instance C is currently in the
APPROVED
state (Validated stage) for a specific Service Item. And, Change Instance D isPENDING
. - The Service Owner validates Change Instance D, resulting in moving to
APPROVED
for the same Service Item. - Because both Change Instance C and D are in the Validated stage, Change Instance C will be
CLOSED
to allow Change Instance D to remain open.
Example 3: Clearing REJECTED
and ERRORED
Change Instances
- If there exists any
REJECTED
/ERRORED
Change Instance. The Consumer must modify the declaration of the related Service Item. Otherwise, the submission will fail. - After submitting modified declaration, Those
REJECTED
/ERRORED
Change Instance will beCLOSED
, and new Change Instances will be created accordingly.
Exception
There is an exception to the standard behavior of managing Stacked Change Instances.
Typically, when a CREATE
change instance transitions to APPROVED
, the associated Service Item enters the IN_SERVICE
state.
Any subsequent submissions for that Service Item will then result in either MODIFY
or DELETE
change instances.
However, if there is an existing CREATE
change instance in the APPROVED
state and a PENDING
MODIFY
change instance becomes APPROVED
, the system will treat this as a special case.
Since the original CREATE
APPROVED
instance is still open (i.e., not COMPLETED
), it will be CLOSED
, and the newly APPROVED
MODIFY
change instance will be converted to a CREATE
APPROVED
instance.
Change Instance History
The processing history of a change instance, including the state, timestamps of changing state, and the user who handled it, is fully recorded. To view the history of a change instance: