plantuml-stdlib / C4-PlantUML

C4-PlantUML combines the benefits of PlantUML and the C4 model for providing a simple way of describing and communicate software architectures
MIT License
6.41k stars 1.1k forks source link

Rel_ and Lay_ are not adhered to. #237

Closed DarwinJS closed 2 years ago

DarwinJS commented 2 years ago

I posted this screenshot and the source 3 days ago: https://github.com/plantuml-stdlib/C4-PlantUML/issues/236

And now it is rendering like this - no matter what I do with Rel and Lay - I can't get back to the expected rendering depicted in that issue.

image

Source ```plantuml @startuml !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml 'LAYOUT_LANDSCAPE() title GitLab Runner and Kubernetes Agent Connections AddRelTag("network", $textColor="red", $lineColor="red", $lineStyle = DashedLine()) AddRelTag("auth", $textColor="orange", $lineColor="orange", $lineStyle = DashedLine()) AddRelTag("control", $textColor="green", $lineColor="green") Boundary(network, "Any Networks", "Private, Internet, etc") { Boundary(runnerenv, "Any Environment", "Private,Cloud,etc") { Container(glrunner, "GitLab Runner") { Component(glrunnertradconn, "Job Acquisition Connection") Component(glrunneragtconn, "Agent Connection") Lay_D(glrunnertradconn,glrunneragtconn) } } Boundary(glinstenv, "Any Environment", "Private,Cloud,etc") { Boundary(glinstance, "Any GitLab Instance", "SaaS, Self-Managed") { Component(kas, "KAS", "Spring Bean") Component(glrails, "GitLab Rails",) } } Rel(glrunnertradconn,glrunneragtconn, "K8s Command", "w/ KUBE_CONTEXT") 'Runner Polling Connection to Job Queue Rel_R(glrunnertradconn, glrails, "Initiates", "SSL", $tags="network") Rel_R(glrunnertradconn, glrails, "Initiates", "Token Auth", $tags="auth") Rel_L(glrails, glrunnertradconn, "Control","Poll & Pull Jobs", $tags="control") Boundary(k8senv, "Any Environment", "Private,Cloud,etc") { Boundary(kasnet, "Any K8s Cluster") { Component(k8sagent, "GL Agent for K8s") } } 'Runner Connection to KAS Rel_R(glrunneragtconn, kas, "Initiates", "SSL", $tags="network") Rel_R(glrunneragtconn, kas, "Control","Push K8s CMDs", $tags="control") Rel_R(glrunneragtconn, kas, "Starts", "Token Auth", $tags="auth") 'K8s Agent to KAS Rel_L(k8sagent, kas, "Initiates", "SSL", $tags="network") Rel_L(k8sagent, kas, "Initiates", "Token Auth", $tags="auth") Rel_R(kas, k8sagent, "Control","Poll & Pull Manifests", $tags="control") 'Layouts prioritized in order - put outer most first Lay_R(runnerenv,glinstenv) Lay_R(glinstenv,k8sagent) Lay_D(glrails,kas) 'Rel_R(glrunner,kas, "Control", "Push CD", $tags="control") 'Rel_R(kas,k8sagent, "Control", "Push CD", $tags="control") } SHOW_LEGEND() @enduml ```
Potherca commented 2 years ago

I've run the example against the last couple of version of PlantUML and C4-PlantUML and I keep getting the above image. I have not been able to reproduce the image from #236.

Was the original image created with a distributed JAR or on the online server?

Tests ## PlantUML versions - **1.2021.1** ![test 2021 1](https://user-images.githubusercontent.com/195757/189837778-af3d617d-fc5f-46c5-97f7-c0f5b1ee5509.png) - **1.2021.9** ![test 2021 9](https://user-images.githubusercontent.com/195757/189837784-bdbf3893-888a-488f-8172-07574a56a9ab.png) - **1.2022.5** ![test 2022 5](https://user-images.githubusercontent.com/195757/189837788-177bee3d-52c8-408c-9415-0067c7289c15.png) - **1.2022.6** ![test 2022 6](https://user-images.githubusercontent.com/195757/189837794-4bfcd1a0-ddf0-40ea-b32a-0ef76eea5af7.png) ## C4 PlantUML versions - **v2.2** ![test-v2 2](https://user-images.githubusercontent.com/195757/189837803-d300f658-bac7-472e-8dcd-05ae83e94394.png) - **v2.3** ![test-v2 3](https://user-images.githubusercontent.com/195757/189837808-d8b9c5b3-440d-4473-b3dc-93b65d1f3f28.png) - **v2.4** ![test-v2 4](https://user-images.githubusercontent.com/195757/189837810-e21490a1-edf1-40ad-ad6a-1b28462aed42.png)
DarwinJS commented 2 years ago

@Potherca - wow thanks for all the testing!

I found that on https://kroki.io, if you select "C4 with PlantUML" it renders how I was expecting.

Screen Shot 2022-09-13 at 11 33 23 AM

Potherca commented 2 years ago

wow thanks for all the testing!

No worries, I do a lot of PlantUML development, so I already have a local test setup. I just throw the .puml file into my setup and the rest goes automagically. Something I hope to add soonish is a visual diff so my test setup can tell me when a change (such as you noted) can be automatically found.

Speaking of which, when i run Kroki with this:

@startuml
version
@enduml

I get:

PlantUML version 1.2022.5(Sat Apr 30 10:55:52 GMT 2022)(GPL source distribution) This version of PlantUML is 136 days old, so you shouldconsider upgrading

Which is odd, since that is not what I see with the distributed 1.2022.5 jar file. I'll have to do some more digging to see where the difference comes from.

Its good to have a reproducible case, that gives me a point to start from. I'll report back here if/when I find something.

DarwinJS commented 2 years ago

I guess the more important detail is that the rendering I am getting directly from plantuml does not follow what is in my file. It blatantly ignores both directional Lay and Rel to put GitLab Runner on the entirely wrong side of the chart.

I have tried reordering the directional directives, reversing them, trying them on top level objects rather than most enclosed, I've tried rotation layouts and changing all the relationships and I've tried moving where Lay and Rel appear in relationship to each other and in relationship to the shape declarations.

It would sure be helpful to have a published list of supposed rendering priorities - both for users and developers to test against.

Something like:

  1. First create all your entities
  2. Then specify ALL Rel_ commands
  3. Then specify ALL Lay commands 3.1. Make sure all Lay commands address ["the objects that have Rel's" OR "the top most boundary objects" OR "the in most objects"] 3.2. Never specify Lay_ commands between elements at different nested levels (If True).

Or perhaps rending priorities mean that you should purposely use directional Rel and Lay statements as soon as you can (as soon as all entities are created).

For instance, some questions: Q1: what is the stronger priority for object relationships - Rel or Lay ? Q2: is it OK or unexpected to use directional versions of both Rel and Lay in the same diagram? Q3: should Rel and Lay commands be used as soon as their target entities exist or is it better to do them altogether after all entities are created or should it not matter at all (i.e. Statement ordering has no effect on layout) ?

The one factor of unpredictable and uncontrollable layout makes the tool quite unusable for my cases.

kirchsth commented 2 years ago

Hi @DarwinJS,

at Q1: Rel is the logical relationship; Lay is only used for the layout if the elements have nor relationship (without an arrow, practically it is an hidden arrow without a label) at Q2: you can use Rel (default without a predefined layout hint), Rel and Lay in one diagram; If you have already a Rel() and you need a layout direction then it is better to use directly Rel#() instead of the 2 calls Rel() and Lay at Q3: I would start with a) all groups/elements b) add relationships (Rel()) c1) if the main position of an element does not match, then it could be simpler to define the elements in a different order (e.g. I changed the order of the boundaries) c2) use Rel# or Lay_# if the layout does not match

BR Helmut

PS.: With following source PlantUML server and kroki.io created the same output for me

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

title GitLab Runner and Kubernetes Agent Connections

AddRelTag("network", $textColor="red", $lineColor="red", $lineStyle = DashedLine())
AddRelTag("auth", $textColor="orange", $lineColor="orange", $lineStyle = DashedLine())
AddRelTag("control", $textColor="green", $lineColor="green")

Boundary(glinstenv, "Any Environment", "Private,Cloud,etc") {
  Boundary(glinstance, "Any GitLab Instance", "SaaS, Self-Managed") {
    Component(kas, "KAS", "Spring Bean")
    Component(glrails, "GitLab Rails",)
    Lay_D(glrails,kas) 
  }
}

Boundary(k8senv, "Any Environment", "Private,Cloud,etc") {
  Boundary(kasnet, "Any K8s Cluster") {
    Component(k8sagent, "GL Agent for K8s")
  }
}

Boundary(network, "Any Networks", "Private, Internet, etc")  {
  Boundary(runnerenv, "Any Environment", "Private,Cloud,etc") {
    Container(glrunner, "GitLab Runner") {
    Component(glrunnertradconn, "Job Acquisition Connection")
    Component(glrunneragtconn, "Agent Connection")
  }
}

Rel(glrunnertradconn,glrunneragtconn, "K8s Command", "w/ KUBE_CONTEXT")

'Runner Polling Connection to Job Queue
Rel_R(glrunnertradconn, glrails, "Initiates", "SSL", $tags="network")
Rel_R(glrunnertradconn, glrails, "Initiates", "Token Auth", $tags="auth")
Rel_R(glrunnertradconn, glrails, "Control","Poll & Pull Jobs", $tags="control")

'Runner Connection to KAS
Rel_R(glrunneragtconn, kas, "Initiates", "SSL", $tags="network")
Rel_R(glrunneragtconn, kas, "Control","Push K8s CMDs", $tags="control")
Rel_R(glrunneragtconn, kas, "Starts", "Token Auth", $tags="auth")

'K8s Agent to KAS
Rel_R(kas, k8sagent, "Initiates", "SSL", $tags="network")
Rel_R(kas, k8sagent, "Initiates", "Token Auth", $tags="auth")
Rel_R(kas, k8sagent, "Control","Poll & Pull Manifests", $tags="control")

'Layouts prioritized in order - put outer most first
Lay_R(runnerenv,glinstenv)
Lay_R(glinstenv,k8sagent)

'Rel_R(glrunner,kas, "Control", "Push CD", $tags="control")
'Rel_R(kas,k8sagent, "Control", "Push CD", $tags="control")
}
SHOW_LEGEND()
@enduml

PPS: @Potherca my first idea was that kroki uses some additional styles/layouts like skinparam ... or !layout elk, but I checked the generated source (which is stored in the svg files too) and found no kroki specific extension

DarwinJS commented 2 years ago

@kirchsth - thanks for your help!

In rebuilding what I have with what you provided I may have discovered a bug.

You accidentally moved Boundary(network, "Any Networks", "Private, Internet, etc") { to no longer include all other shapes.

When I moved it back to the top - everything stays stable.

HOWEVER, If I move the closing brace from enclosing the Rel and Lay commands and put it right before the first Rel - I get the messed up version.

It seems like if you have an "all enclosing" boundary - it must also enclose all the relationships that occur with in it.

This also includes SHOW_FLOAGING_LEGEND() - if it is not inside the all enclosing boundary.

Working Version:

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

'GitLab Colors
' Light Orange: #FCA326, Medium Orange: #FC6D26, Dark Orange: #E24329

'Layout Rendering Priorities
' 1. With dynamic rendering tools (e.g. VS Code plugin) do NOT trust the first rendering 
'    as it is shifty when adding stuff - even comments. Wait for a bit or close and reopen preview panel.
' 2. Create all components, containers and boundaries first - in order top to bottom or left to right
' 3. Use Rel (directionless) where possible.
' 3. Use Rel_<direction> to force shape layouts.
'    3.a. Order inner objects first when it creates the desired result.
'    3.b. Try NOT to apply order to both inner elements and elements that enclose them.
'    3.c. Make all orderings at the same nesting level whenever possible.
' 4. Add "Lay_<direction>" to force any layouts that Rel_<direction> does not resolve.
' 5. If you have an "All enclosing" boundary, all of the above Rel and Lay statements must
'    be inside the "All enclosing" boundary.
' 6. Legend statements must come after at least one usage of each of the elements you want the legend 
'    to contain.

title GitLab Runner and Kubernetes Agent Connections

AddRelTag(network, $textColor="red", $lineColor="red", $lineStyle = DashedLine(),$legendText="Network Connection")
AddRelTag(auth, $textColor="orange", $lineColor="orange", $lineStyle = DashedLine(),$legendText="Authentication")
AddRelTag(control, $textColor="green", $lineColor="green",$legendText="App Control Flow")
UpdateElementStyle(boundary, $bgColor="transparent",$fontColor="black", $borderColor="gray",$legendText="Network or Environment")
UpdateElementStyle(component,$bgColor="#FC6D26", $borderColor="transparent",$legendText="GitLab Component")
UpdateElementStyle(container,$bgColor="#FCA326", $borderColor="transparent",$legendText="GitLab Container")
AddBoundaryTag(invisible, $bgColor="transparent",$borderColor="transparent")

Boundary(network, "Any Networks", "Private, Internet, etc")  {
  Boundary(runnerenv, "Any Environment", "Private,Cloud,etc") {
      Container(glrunner, "GitLab Runner") {
      Component(glrunnertradconn, "Job Acquisition Connection")
      Component(glrunneragtconn, "Agent Connection")
    }
  }

  Boundary(k8senv, "Any Environment", "Private,Cloud,etc") {
    Boundary(kasnet, "Any K8s Cluster") {
      Component(k8sagent, "GL Agent for K8s")
    }
  }

  Boundary(glinstenv, "Any Environment", "Private,Cloud,etc", $tags="network") {
    Container(glinstance, "Any GitLab Instance", "SaaS, Self-Managed") {
      Component(kas, "KAS")
      Component(glrails, "GitLab Rails",)
    }
  }

  Rel(glrunnertradconn,glrunneragtconn, "K8s Command", "w/ KUBE_CONTEXT")

  'Runner Polling Connection to Job Queue
  setIndex(1)
  Rel_R(glrunnertradconn, glrails, "Initiates", "SSL", $tags="network")
  Rel_R(glrunnertradconn, glrails, "Initiates", "Token Auth", $tags="auth")
  Rel_R(glrunnertradconn, glrails, "Control","Poll & Pull Jobs", $tags="control")

  'Runner Connection to KAS
  setIndex(1)
  Rel_R(glrunneragtconn, kas, "Initiates", "SSL", $tags="network")
  Rel_R(glrunneragtconn, kas, "Starts", "Token Auth", $tags="auth")
  Rel_R(glrunneragtconn, kas, "Control","Push CD K8s CMDs", $tags="control")

  'K8s Agent to KAS
  setIndex(1)
  Rel_R(kas, k8sagent, "Initiates", "SSL", $tags="network")
  Rel_R(kas, k8sagent, "Initiates", "Token Auth", $tags="auth")
  Rel_R(kas, k8sagent, "Control","Poll & Pull Manifests", $tags="control")
  Rel_R(kas, k8sagent, "Control","Push CD K8s CMDs", $tags="control")

  'Layouts prioritized in order - put outer most first
  Lay_D(glrails,kas) 
  Lay_R(runnerenv,glinstenv)
  Lay_R(glinstenv,k8sagent)

'  Boundary(legend3, "Legend", $tags="invisible") {
'    note as legend4
'      <#white,#white>|<color:$LEGEND_TITLE_COLOR>Legend</color> |
'      $showActiveLegendEntries($tagDefaultLegend)
'      $showActiveLegendEntries($tagCustomLegend)
'    endnote
'  }
'  Lay_R(glinstenv,legend3)
'Closing brace for all enclosing "Any Networks" must stay here
}
'SHOW_LEGEND()

center footer \n\nEach Network Environment must provided suitable network routing, DNS and firewall configuration to allow\nthe connection initiation and return conversations indicated in the lines marked with "[Network]" boxes.\n\nThe GitLab Instance, Runners and Kubernetes Agents may all be in the same network environment - the **most complex case** is depicted because \nit would be the norm if using GitLab.com SaaS with self-hosted runners to manage Kubernetes clusters in a variety of other environments.\n\nAll dark orange boxes are part of a GitLab Instance.\n\nOnly the GitLab K8s integration is required for a pure GitOps workflow (depicted as "(G)").

@enduml

image

Broken in prior way (only moved closing brace):

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

'GitLab Colors
' Light Orange: #FCA326, Medium Orange: #FC6D26, Dark Orange: #E24329

'Layout Rendering Priorities
' 1. With dynamic rendering tools (e.g. VS Code plugin) do NOT trust the first rendering 
'    as it is shifty when adding stuff - even comments. Wait for a bit or close and reopen preview panel.
' 2. Create all components, containers and boundaries first - in order top to bottom or left to right
' 3. Use Rel (directionless) where possible.
' 3. Use Rel_<direction> to force shape layouts.
'    3.a. Order inner objects first when it creates the desired result.
'    3.b. Try NOT to apply order to both inner elements and elements that enclose them.
'    3.c. Make all orderings at the same nesting level whenever possible.
' 4. Add "Lay_<direction>" to force any layouts that Rel_<direction> does not resolve.
' 5. If you have an "All enclosing" boundary, all of the above Rel and Lay statements must
'    be inside the "All enclosing" boundary.
' 6. Legend statements must come after at least one usage of each of the elements you want the legend 
'    to contain.

title GitLab Runner and Kubernetes Agent Connections

AddRelTag(network, $textColor="red", $lineColor="red", $lineStyle = DashedLine(),$legendText="Network Connection")
AddRelTag(auth, $textColor="orange", $lineColor="orange", $lineStyle = DashedLine(),$legendText="Authentication")
AddRelTag(control, $textColor="green", $lineColor="green",$legendText="App Control Flow")
UpdateElementStyle(boundary, $bgColor="transparent",$fontColor="black", $borderColor="gray",$legendText="Network or Environment")
UpdateElementStyle(component,$bgColor="#FC6D26", $borderColor="transparent",$legendText="GitLab Component")
UpdateElementStyle(container,$bgColor="#FCA326", $borderColor="transparent",$legendText="GitLab Container")
AddBoundaryTag(invisible, $bgColor="transparent",$borderColor="transparent")

Boundary(network, "Any Networks", "Private, Internet, etc")  {
  Boundary(runnerenv, "Any Environment", "Private,Cloud,etc") {
      Container(glrunner, "GitLab Runner") {
      Component(glrunnertradconn, "Job Acquisition Connection")
      Component(glrunneragtconn, "Agent Connection")
    }
  }

  Boundary(k8senv, "Any Environment", "Private,Cloud,etc") {
    Boundary(kasnet, "Any K8s Cluster") {
      Component(k8sagent, "GL Agent for K8s")
    }
  }

  Boundary(glinstenv, "Any Environment", "Private,Cloud,etc", $tags="network") {
    Container(glinstance, "Any GitLab Instance", "SaaS, Self-Managed") {
      Component(kas, "KAS")
      Component(glrails, "GitLab Rails",)
    }
  }
'Opps closing brace in wrong place
}

  Rel(glrunnertradconn,glrunneragtconn, "K8s Command", "w/ KUBE_CONTEXT")

  'Runner Polling Connection to Job Queue
  setIndex(1)
  Rel_R(glrunnertradconn, glrails, "Initiates", "SSL", $tags="network")
  Rel_R(glrunnertradconn, glrails, "Initiates", "Token Auth", $tags="auth")
  Rel_R(glrunnertradconn, glrails, "Control","Poll & Pull Jobs", $tags="control")

  'Runner Connection to KAS
  setIndex(1)
  Rel_R(glrunneragtconn, kas, "Initiates", "SSL", $tags="network")
  Rel_R(glrunneragtconn, kas, "Starts", "Token Auth", $tags="auth")
  Rel_R(glrunneragtconn, kas, "Control","Push CD K8s CMDs", $tags="control")

  'K8s Agent to KAS
  setIndex(1)
  Rel_R(kas, k8sagent, "Initiates", "SSL", $tags="network")
  Rel_R(kas, k8sagent, "Initiates", "Token Auth", $tags="auth")
  Rel_R(kas, k8sagent, "Control","Poll & Pull Manifests", $tags="control")
  Rel_R(kas, k8sagent, "Control","Push CD K8s CMDs", $tags="control")

  'Layouts prioritized in order - put outer most first
  Lay_D(glrails,kas) 
  Lay_R(runnerenv,glinstenv)
  Lay_R(glinstenv,k8sagent)

'  Boundary(legend3, "Legend", $tags="invisible") {
'    note as legend4
'      <#white,#white>|<color:$LEGEND_TITLE_COLOR>Legend</color> |
'      $showActiveLegendEntries($tagDefaultLegend)
'      $showActiveLegendEntries($tagCustomLegend)
'    endnote
'  }
'  Lay_R(glinstenv,legend3)

'SHOW_LEGEND()

center footer \n\nEach Network Environment must provided suitable network routing, DNS and firewall configuration to allow\nthe connection initiation and return conversations indicated in the lines marked with "[Network]" boxes.\n\nThe GitLab Instance, Runners and Kubernetes Agents may all be in the same network environment - the **most complex case** is depicted because \nit would be the norm if using GitLab.com SaaS with self-hosted runners to manage Kubernetes clusters in a variety of other environments.\n\nAll dark orange boxes are part of a GitLab Instance.\n\nOnly the GitLab K8s integration is required for a pure GitOps workflow (depicted as "(G)").

@enduml

image

The above, along with your explanations has cause me to devise this set of possible ordering rules for building diagrams - would love your review:

'Layout Rendering Priorities ' 1. With dynamic rendering tools (e.g. VS Code plugin) do NOT trust the first rendering ' as it is shifty when adding stuff - even comments. Wait for a bit or close and reopen preview panel. ' 2. Create all components, containers and boundaries first - in order top to bottom or left to right ' 3. Use Rel (directionless) where possible. ' 3. Use Rel to force shape layouts. ' 3.a. Order inner objects first when it creates the desired result. ' 3.b. Try NOT to apply order to both inner elements and elements that enclose them. ' 3.c. Make all orderings at the same nesting level whenever possible. ' 4. Add "Lay" to force any layouts that Rel_ does not resolve. ' 5. If you have an "All enclosing" boundary, all of the above Rel and Lay statements must ' be inside the "All enclosing" boundary. ' 6. Legend statements must come after at least one usage of each of the elements you want the legend ' to contain.

DarwinJS commented 2 years ago

Whew, when I switch from VS Code on Windows to VS Code on Mac I was back to the same problem.

The only way I can resolve it and things seem to make sense is not to have an all enclosing boundary at all - the below works on plantuml.com.

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

'GitLab Colors
' Light Orange: #FCA326, Medium Orange: #FC6D26, Dark Orange: #E24329

'Layout Rendering Priorities
' 1. With dynamic rendering tools (e.g. VS Code plugin) do NOT trust the first rendering 
'    as it is shifty when adding stuff - even comments. Wait for a bit or close and reopen preview panel.
' 2. Create all components, containers and boundaries first - in order top to bottom or left to right
' 3. Use Rel (directionless) where possible.
' 3. Use Rel_<direction> to force shape layouts.
'    3.a. Order inner objects first when it creates the desired result.
'    3.b. Try NOT to apply order to both inner elements and elements that enclose them.
'    3.c. Make all orderings at the same nesting level whenever possible.
' 4. Add "Lay_<direction>" to force any layouts that Rel_<direction> does not resolve.
' 5. If you have an "All enclosing" boundary, all of the above Rel and Lay statements must
'    be inside the "All enclosing" boundary.
' 6. Legend statements must come after at least one usage of each of the elements you want the legend 
'    to contain.

title GitLab Runner and Kubernetes Agent Connections

AddRelTag(network, $textColor="red", $lineColor="red", $lineStyle = DashedLine(),$legendText="Network Connection")
AddRelTag(auth, $textColor="orange", $lineColor="orange", $lineStyle = DashedLine(),$legendText="Authentication")
AddRelTag(control, $textColor="green", $lineColor="green",$legendText="App Control Flow")
UpdateElementStyle(boundary, $bgColor="transparent",$fontColor="black", $borderColor="gray",$legendText="Network or Environment")
UpdateElementStyle(component,$bgColor="#FC6D26", $borderColor="transparent",$legendText="GitLab Component")
UpdateElementStyle(container,$bgColor="#FCA326", $borderColor="transparent",$legendText="GitLab Container")
AddBoundaryTag(invisible, $bgColor="transparent",$borderColor="transparent")

Boundary(network1, "Any Network", "Private, Internet, etc")  {
  Boundary(runnerenv, "Any Environment", "Private,Cloud,etc") {
      Container(glrunner, "GitLab Runner") {
      Component(glrunnertradconn, "Job Acquisition Connection")
      Component(glrunneragtconn, "Agent Connection")
    }
  }
}

Boundary(network2, "Any Network", "Private, Internet, etc")  {
  Boundary(k8senv, "Any Environment", "Private,Cloud,etc") {
    Boundary(kasnet, "Any K8s Cluster") {
      Component(k8sagent, "GL Agent for K8s")
    }
  }
}

Boundary(network3, "Any Network", "Private, Internet, etc")  {
  Boundary(glinstenv, "Any Environment", "Private,Cloud,etc", $tags="network") {
    Container(glinstance, "Any GitLab Instance", "SaaS, Self-Managed") {
      Component(kas, "KAS")
      Component(glrails, "GitLab Rails",)
    }
  }
}
  Rel(glrunnertradconn,glrunneragtconn, "K8s Command", "w/ KUBE_CONTEXT")

  'Runner Polling Connection to Job Queue
  setIndex(1)
  Rel_R(glrunnertradconn, glrails, "Initiates", "SSL", $tags="network")
  Rel_R(glrunnertradconn, glrails, "Initiates", "Token Auth", $tags="auth")
  Rel_R(glrunnertradconn, glrails, "Control","Poll & Pull Jobs", $tags="control")

  'Runner Connection to KAS
  setIndex(1)
  Rel_R(glrunneragtconn, kas, "Initiates", "SSL", $tags="network")
  Rel_R(glrunneragtconn, kas, "Starts", "Token Auth", $tags="auth")
  Rel_R(glrunneragtconn, kas, "Control","Push CD K8s CMDs", $tags="control")

  'K8s Agent to KAS
  setIndex(1)
  Rel_R(kas, k8sagent, "Initiates", "SSL", $tags="network")
  Rel_R(kas, k8sagent, "Initiates", "Token Auth", $tags="auth")
  Rel_R(kas, k8sagent, "Control","Poll & Pull Manifests", $tags="control")
  Rel_R(kas, k8sagent, "Control","Push CD K8s CMDs", $tags="control")

  'Layouts prioritized in order - put outer most first
  Lay_D(glrails,kas) 
  Lay_R(runnerenv,glinstenv)
  Lay_R(glinstenv,k8sagent)

'  Boundary(legend3, "Legend", $tags="invisible") {
'    note as legend4
'      <#white,#white>|<color:$LEGEND_TITLE_COLOR>Legend</color> |
'      $showActiveLegendEntries($tagDefaultLegend)
'      $showActiveLegendEntries($tagCustomLegend)
'    endnote
'  }
'  Lay_R(glinstenv,legend3)

SHOW_FLOATING_LEGEND()

center footer \n\nEach Network Environment must provided suitable network routing, DNS and firewall configuration to allow\nthe connection initiation and return conversations indicated in the lines marked with "[Network]" boxes.\n\nThe GitLab Instance, Runners and Kubernetes Agents may all be in the same network environment - the **most complex case** is depicted because \nit would be the norm if using GitLab.com SaaS with self-hosted runners to manage Kubernetes clusters in a variety of other environments.\n\nAll dark orange boxes are part of a GitLab Instance.\n\nOnly the GitLab K8s integration is required for a pure GitOps workflow (depicted as "(G)").
@enduml

image

Potherca commented 2 years ago

Whew. :sweat_smile:

There is a lot of useful information here! that hard part for me is: how do we document this (and where?) so that these sorts of scenarios are easily explained and usable for others? :thinking:

DarwinJS commented 2 years ago

@Potherca - by a pull request of course 😄 : https://github.com/plantuml-stdlib/C4-PlantUML/pull/239