Skip to content

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:

VM:
    name: str
    cpu: int
    ram: int
LoadBalancer:
    name: str
    algorithm: str

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 existing VM, 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 is PENDING.
  • 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 be CLOSED, 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:

GET /v1/orcabase/serviceowner/change_instances/<change_instance_id>/history/ HTTP/1.1
Content-Type: application/json
Authorization: Token <token>
from netorca_sdk import NetOrca

netorca = Netorca(fqdn=<YOUR_NETORCA_BASE_URL>, api_key=<YOUR_NETORCA_API_KEY>)
change_instance_history = netorca.change_instance_history(change_instance_id=<change_instance_id>, context="consumer")