-
Notifications
You must be signed in to change notification settings - Fork 6
/
models.txt
1302 lines (758 loc) · 47.3 KB
/
models.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Models
## A unit of packaging for Meshery’s logical object representation
```
See also: Meshery Model Generation
```
# Prologue and Challenge
As a cloud-native management plane, Meshery should be able to:
* Empower its users with a wide range of tools that provide support for the majority of the systems in the cloud and cloud native ecosystems.
* Abstract away the system specific requirements and help the users focus on getting things done.
There has to be a model internal to Meshery that can capture all these use cases and serve as a way for communicating consistently. Meshery currently has an object model but there are some problems with it:
1. The current model has been built using [OAM](https://oam.dev/) spec, which is an awkward fit, constraining our use cases.
2. The current model is centered around Service Meshes and not the broader Cloud and Cloud Native ecosystems.
3. The current model lacks well-defined boundaries around the constructs.
## Guiding Principles
Adhere to the following design principles:
1. **Establish a set of constructs that will be used across Meshery**
2. **Make sure the boundaries are clearly defined with vigil eye to extensibility**
Clearly define what the responsibilities of a construct are and are not.
Allow users to extend the constructs and create new constructs.
3. **Reuse where possible. Differentiate where feasible.**
Build upon other works while uplifting and sprinkling in unique value. If it makes sense, make use of the things we already have in our model.
4. **Be end user-centric; Enable the business function.**
Simplify. Networking and distributed systems are hard; Connect the dots between dynamic infrastructure and the business.
## Design Goals
The goal is to have a model for Meshery that:
1. Sets a foundation for the project to build and expand on (are versioned).
2. Facilitates a consistent way of communicating between multiple components.
3. Provides the ability to understand constructs of different systems in the cloud native ecosystem and beyond.
# Model Constructs
# Model Packaging
Each model package can be imported and exported from the system as OCI-compatible images, making them portable (a design goal), abstracting their complexity, and encapsulating potential intellectual property that users might have invested into their models. Model packages are versioned and bundle any number of components, relationships, policies, connections and credentials. For example:
### Model Schema
```
apiVersion: core.meshery.io/v1alpha1
kind: ModelDefinition
metadata:
name:
version: 1.19
spec:
schematic:
cue: |
designations: vs : kubernetes
outputs : vs : {
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
spec: {
# rest of the configuration for VS
}
}
parameters: {
param1: string
param2: int
# user inputs
}
```
# Glossary: Core Constructs
Every construct will be represented in three forms (two static and one dynamic).
1. **Schema** (static) - the skeletal structure representing a logical view of the size, shape, characteristics of a construct.
1. _Example: meshery/schemas_
2. **Definition** (static) - An implementation of the Schema containing specific configuration for the construct at-hand.
2. _Example: Kubernetes Pod_
3. **Declaration** (static) - A defined construct; A specific deof the Definition.
3. _Example: NGINX container as a Kubernetes Pod_
4. **Instance** (dynamic) - A realized construct (deployed/discovered); An instantiation of the Declaration.
4. _Example: NGINX-as234z2 pod running in cluster_
MeshModel supports a common substrate of operands to support granularly, expressively selectors for matching (or not matching) model constructs. The set of supported operands in MeshModel is a direct representation of those supported by Cuelang and defined by RFC xxx / regex xxx. Sample operands:
1. * - wildcard
2. ? - ….
3. ! - ! means NOT
4. <, >, =, !=, …
The absence of a value for a given attribute in a Definition means: — something that has to be written per Construct.
## Component
Components are designed to be portable, accessible, versioned and easily manageable.
Components are a way of exposing the capabilities of the underlying platform. In the case of application development, Components are entities that are registered by platform engineers and used by operators.
`ComponentDefinition`, as the name implies, is the definition of a `Component` which will be stored in the `Registry`. `Components` are instances of `ComponentDefinitions`.
A `Component` on evaluation will output a set of manifests which will be sent to the appropriate `Registrant` (host) for further handling.
Any user should be able to easily create his own `ComponentDefinition` and publish it so that others can make use of it.
### Component Schema
```
apiVersion: core.meshery.io/v1alpha1
kind: ComponentDefinition
format: "CUE",
metadata:
name: VirtualService
version: 1.19
schema:
cue: |
designations: vs : kubernetes
outputs : vs : {
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
spec: {
# rest of the configuration for VS
}
}
parameters: {
param1: string
param2: int
# user inputs
}
```
`designations` is a map with the names of the `outputs` as keys and the `managers` as the values.
```
managers are entities that know how to manage(provision/deprovision/update) a certain manifest generated when instantiating Components.
```
`outputs` is a map with the names as keys and manifest as values.
```
parameters is a map with the names as keys and the type as keys. These parameters define the configuration parameters required while instantiating a Component.
```
Upon instantiating the `ComponentDefintion` with the necessary parameters, some manifests (like the Kubernetes `VirtualService` resource) will be sent to the `Kubernetes` host as assigned through the `designations` field. The host ( `Kubernetes` in this case) should know how to deal with this manifest.
_How will we leverage the power of cue while defining schemas?_
## Meshery’s Core Components
Currently Meshery has only 1 core component: Application. Below is the ComponentDefinition for it.
{
"kind": "Application",
"apiVersion": "core.meshmodel.dev/v1alpha1",
"display-name": "Application",
"format": "JSON",
"metadata": {
"Helm Chart": "",
"Logo URL": "",
"Primary Color": "",
"Project Name": "Meshery",
"SVG_Color": "",
"SVG_White": "",
"Secondary Color": "",
"Shape": "circle"
},
"model": {
"name": "core",
"version": "v1.0.0",
"display-name": "core",
"category": "App Deployment",
"sub-category": ""
},
"schema": "{\n \"$id\": \"http://meshery.layer5.io/definition/Workload/Application\",\n \"$schema\": \"http://json-schema.org/draft-07/schema\",\n \"title\": \"Application\",\n \"type\": \"object\",\n \"properties\": {\n \"replicas\": {\n \"type\": \"integer\"\n },\n \"advanced\": {\n \"type\": \"object\",\n \"properties\": {\n \"create_service\": {\n \"type\": \"boolean\",\n \"title\": \"Expose as a Service\",\n \"default\": true\n }\n }\n },\n \"containers\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"image\": {\n \"type\": \"string\"\n },\n \"commands\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"ports\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"default\": \"http\"\n },\n \"containerPort\": {\n \"type\": \"integer\"\n }\n },\n \"minItems\": 1,\n \"required\": [\"containerPort\"]\n }\n },\n \"envs\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"value\": {\n \"type\": \"string\"\n }\n }\n }\n }\n },\n \"required\": [\"name\", \"image\", \"ports\"],\n \"minItems\": 1\n }\n }\n },\n \"required\": [\"replicas\", \"containers\"]\n}\n"
}
## Design
A `Design` consists of `Components` and `Patterns`. `Design` is the deployable unit in Meshery. `Designs` are how the users can describe the desired infrastructure.
There **cannot** be two components with the same name
### Design Schema
```
apiVersion: core.meshery.io/v1alpha1
kind: Design
metadata:
description: A sample design for testing
name: sampledesign
spec:
components:
- name: httpbin
type: server
settings:
port: 80
replicas: 3
image: docker.io/kennethreitz/httpbin
Properties: (q)
meshmap:
position: x: 20,
patterns:
```
* `name: simplecb`
```
type: circuitbreaker
settings:
applyTo: httpbin
interval: 3s
consecutive5xxErrors: 2
```
## Pattern
A `Pattern` is an entity that augments the operational behavior of a deployed instance of a Design. A Pattern can be applied to a `Component` or a `Design`. `Patterns` define a common (and best) practice of both configuring and operating cloud-native application functionality. `Patterns` are read-only.
### Pattern Schema
```
apiVersion: core.meshery.io/v1alpha1
kind: PatternDefinition
metadata:
annotations:
description: circuit breaker pattern
name: circuitbreaker
spec:
schematic:
cue: |
designations: destinationrule: kubernetes
parameters: {
maxConnections: *1 | int
http1MaxPendingRequests: *1 | int
maxRequestsPerConnection: *1
consecutive5xxErrors: *1 | int
interval: *"1s" | string
baseEjectionTime: *"3m" | string
maxEjectionPercent: *100 | int
applyTo: string
}
outputs: destinationrule: {
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: context.name
spec:
host: parameters.applyTo
trafficPolicy:
connectionPool:
tcp:
maxConnections: parameters.maxConnections
http:
http1MaxPendingRequests: parameters.http1MaxPendingRequests
maxRequestsPerConnectio: parameters.maxRequestsPerConnection
outlierDetection:
consecutive5xxErrors: parameters.consecutive5xxErrors
interval: parameters.interval
baseEjectionTime: parameters.baseEjectionTime
maxEjectionPercent: parameters.maxEjectionPercent
}
modify: [parameters.applyTo] : {
...
}
```
A `Pattern` on evaluation may:
1. Generate a set of manifests just like `Components`
2. Modify some configurational parameters of the `Design` to which it is applied
1. This modification will be restricted to certain parts of the `Design`.
`designations`, `outputs` and `parameters` have the same meaning as in <code>[Components](http://Component)</code> .
`modify` is used to modify some configurational parameters of a certain component in the `Design`. For example, it can be used to add a certain label to a particular `Component`.
## Traits
A trait is an entity that offers additional detail about the Component (every entity in Meshery is a Component) to which it is attached to. For example:
1. A trait called `Meshmap` can be attached to a Component which will have information such as node position, node color etc. that makes sense only inside MeshMap.
2. Metrics
1. ref
3. Actions
2. ref
4. Color
3. Primary: [ hex | rgba() ]
4. Secondary: [ hex | rgba() ]
5. Logo [ filename/URI ]
6. Element Type [ Node | Node Group ]
7. Receiver
5. ComponentRef.types
1. [ EnvoyFilters |eBPFprograms ]
2. [ Sidecar]
<table>
<tr>
<td>
<strong>Kubernetes</strong>
</td>
<td><strong>Meshery</strong>
</td>
<td><strong>Crossplane</strong>
</td>
<td><strong>OAM</strong>
</td>
</tr>
<tr>
<td>Deployment
</td>
<td>Design : Pattern (special type)
</td>
<td>Composition
</td>
<td>Application
</td>
</tr>
<tr>
<td>Pods
</td>
<td>Node : Component
</td>
<td>XRs : XRDs
</td>
<td>
</td>
</tr>
<tr>
<td>Metadata / spec
</td>
<td>Attributes
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
</td>
<td>MeshSync Object: K8s Object
</td>
<td>Managed Resource
</td>
<td>
</td>
</tr>
</table>
## Relationships
**Example**
Using the use case where you want to make it such that when an edge is drawn from a Kubernetes `Service` to a Kubernetes `Pod`, the port fields in the `pod` configuration gets automatically filled with the details on the edge. You are just interpreting the relationship that exists between the `Pod` and the `Service` components.
`Relationships` define the genealogy between one or more interconnected `Components`. Just as in familial relationships, MeshModel `Relationships` are represented in a variety of forms very much resembling familiar ancestral lineage, including hierarchical relationships such as direct parent and child relationship as well as any number of layers of indirect grandparent and grandchild relationships. Peer relationships like that of siblings take on different types such as `network` and `dependency`. This can have multiple effects depending on what context it is being used.
**<code>Relationships</code> have <code>metadata</code>, <code>selectors</code> and some optional parameters. </strong>
As someone who creates `Designs` and `Components`, It would be useful If I can have some assistance in visualizing the relationships that exist between multiple `Components`. When some `Components` are related to each other in a `Design`, MeshMap should show how they are related visually to the extent possible.
Treating the Relationships the same way as that of Components is not the ideal approach since the use case for the Relationships are different. This approach will be replaced later with a better alternative like a Graph Database.
### Selectors
Selectors are structured as an array, wherein each entry comprises a `from(self)` field and a `to(other)` field (`[from: [{..}], to: [{..}]]`) (from and to will be **CUE** values), delineating the components involved in a particular relationship. Each item of the selector define the constraints to be satisfied for a particular relationship to exist, the selectors act as a scoping within a relationship enabling more flexibility and re-use when defining relationships.
The components within the same selector or each item of the selector relates to each other via 1:many kind of relation. i.e. Each object inside the `from `relates to each item inside the `two` field within a particular selector. \
\
When defining relationships that involve a large number of combinations between `from` and `to`, having selectors as an array provides a mechanism to organize and manage these relationships. This prevents the need for crafting complex deny attributes and facilitates easier maintenance. \
\
This arrangement enhances flexibility and reusability in the definition and configuration of relationships among components.
Eg: WASMFilter - EnvoyFilter,
ConfigMap - Pod,
ConfigMap - Deployment
* DaemonSets
* Jobs
* StatefulSets,
These pairs have `hierarchical inventory relationship`, the policy backing this relationship and the visual paradigm are the same, If these pairs are defined in a single selector then the `deny` attribute needs to be carefully crafted to ensure disambiguity because relationship between ConfigMap and EnvoyFilter needs to be restricted. This can quickly become difficult to maintain due to large number of combinations possible between `from` and `to`.
### Actions
1. Patch
The Patch represents an action which updates the configuration of the components involved in a relationship. The component from which configuration will be applied is called as `mutator` and the component to which configuration is applied is called as `mutated`.
The jsonpath of the component property (`mutator`), from which patch will be applied is captured in the attribute `mutatorRef.`
The jsonpath of the component property (`mutated`), to which patch will be applied is captured in the attribute `mutatedRef.`
The schema of the `patch` action is defined at [patch schema.](https://github.com/meshery/schemas/blob/849c40f5766be18d36a7e250334d43e085b103a0/schemas/meshmodel/schemas/selectors.json#L40)
NOTE: The `mutatorRef` sequence must correspond precisely to the `mutatedRef` sequence. For instance, if `mutatorRef` is defined as `[[config, url], [config, name]]`, and `mutatedRef `as `[[configPatch, value], [name]]` then during the patch action, the value at the path [config, url] is patched to mutated component at `[configPatch, value]`, and values at the path` [config, name]` is patched at `[name]`.
#### Operators
Operators help us in adding dynamic flavour to the static relationship definition. It helps in defining relationships which are easy to define but powerful in nature. They are similar to CEL in K8s, but instead they are evaluated in the OPA policies.
For use cases like:
1. ConfigMap can be used as volume as well as Environment variable, the mutatorRef and mutatedRef for both of the scenario is totally different. To cater this need, we can either define another selector in the same relationship definition or we can use “OR” operator to express them concisely. The former introduces duplication, increases the length of the relationship, can cause confusion if not reviewed carefully (as only a part of it will be different in both the scenarios). The later approach, ensures concise and powerful representation.
2. Kubernetes resources are highly configurable and forms relationships with each other in many different ways. For instance, PVC can be bound to a PV on the basis of
1. storageClass, matchSelelctors and labels of PV and PVC
OR
2. claimRef properties of PVC.
Suppose in a design consisting of Pod, PV and PVCs, the storageClassName listed in the PV and PVC is same but the constraints defined in 2.a is not satisfied even then as PVC has claimRef to a correct PV kuberentes will bind the PVC to that particular PV. Hence, we should be flexible and open to both type of constraints. This can be addressed by having different relationship but usage of “OR” operator seems more adequate.
Hence for these such scenarios operators are helpful.
**Interaction during relationship creation.**
Building upon the above ConfigMap example, we still have a unresolved query..
1. Out of all available containers inside the Deployment/Pod to which specific container the configMap should be mounted?
2. Or for Network relationship, out of the all available containers which container to expose?
Such questions cannot be completely addressed by the relationship definition itself, as it involves user’s choice. Therefore, to cater these scenarios there’s a need for “Interaction during relationship creation”. (Ideally handled in [Tier-1 eval](#tier-1-client-side-23))
In some cases we can choose an answer with complete accuracy foreg: If there’s a single container or no containers then we can automatically default to 1st container or create a new one.
But in other situation it is difficult to answer this query.
To support this interaction, the policies during the Tier-2 evaluation, needs to be aware of the user’s choice.
Eg: Out of 3 available containers (1 init and 2 app container) the second container is chosen.
This information needs to be passed along when Tier-2 eval is invoked.
The functionality of [Patch](#actions-14) action and specifically, `mutatorRef` and `mutatedRef` schema needs to be updated to support variables in their property/jsonPath.
```
Eg: The path will be parameterized as follow.
mutatorRef: [[name]]
mutatedRef: [[settings, spec, containers, $container_index, envFrom, $variable_index configMapRef, Name]]
Assume values of $container_index = 2 and $variable_index = 1
The above example showcases a relationship were the 1st set of environment variables present in the 2nd container of a Pod is being replaced by the env variables specified by the configMap.
Since the parameters/variable will be part of relationship definition(mutatedRef/mutatorRef), the Tier-1 eval can reference the relationship definition and can invoke a set of interactions.
The chosen values for these parameters as part of interaction will be passed along as an input to the Tier-2 eval.
Requirement: The inputs should be key-value mapping, scoped within the context of relationship to ensure disambiguity from the parameters of other relationships.
Eg: inputs: {
hierarchical_relationship: {
container_index: 2,
variable_index: 1
}
}
// We will require to consider for which particular selector these values are for, as the variable names will not necessarily be unique in the relationship definition. Eg: The contianer_index will also be used for secret mount, PVC mount …
// The above schema is just for representation.
```
At the [Tier-2: Server side eval](#tier-2-first-part-of-tier-2-eval-server-side-eval-24), stage-3, the inputs will be sanitized and processed.
In the example below, the `Relationship` goes from all the Kubernetes Pod Components (different versions included) to all the Components that have the `Networking` model category.
Scope: package / model level.
### Relationship Schema
```
apiVersion: core.meshery.io/v1alpha1
kind: RelationshipDefinition
metadata:
name: Network Edge Relationship
description: Network edge relationship
type: edge
sub-type: network
status:
spec:
schematic:
cue: |
selectors:[
allow:
from: [self | other ]
```
* `kind: (assume !* when null)`
```
model: (assume !* when null)
version: (assume * when null)
patch:
patchStrategy: replace
mutatorRef: (#jsonref to value from where patch should be applied.)
to: [self | other ]
```
* `kind: (assume * when null) (a package can reference components from another package)`
```
model: (assume * when null)
version: (assume * when null)
patch:
patchStrategy: replace
mutatedRef: (#jsonRef to value that should be patched.)
deny:
to: [self | other ]
```
* `kind: (assume * when null) (a package can reference components from another package)`
```
model: (assume * when null)
version: (assume * when null)
from: [self | other ]
```
* `kind: (assume * when null) (a package can reference components from another package)`
```
model: (assume * when null)
version: (assume * when null)
]
```
<p id="gdcalert3" ><span style="color: red; font-weight: bold">>>>>> gd2md-html alert: inline image link here (to images/image3.png). Store image on your image server and adjust path/filename/extension if necessary. </span><br>(<a href="#">Back to top</a>)(<a href="#gdcalert4">Next alert</a>)<br><span style="color: red; font-weight: bold">>>>>> </span></p>
![alt_text](images/image3.png "image_tooltip")
_Figure: Example of a <code>from: self</code> reference</em>
### Things to Keep in Mind while creating RelationshipDefinitions
1. Relationships are defined only between Components.
2. The values for `Kind, Version ` and `Model` are case-sensitive
3. The convention is to use camel-casing for `Kind` and `SubType` values.
4. Absence of a field means in the selector means “*” (or wildcard).
1. If we have a selector with {Kind: Pod, Model: Kubernetes}, the absence of the Version field here means that all the versions of the Kubernetes Pod resource (e.g. k8s.io/v1/betav2) will match.
5. In the event of conflicting Relationship Definitions, union between them is taken.
2. If we have two Relationships, one from `(Component A)` to `(Component B and Component F)`, and another from `(Component A)` to `(Component B and Component C), `then it is similar to having a Relationship from `Component A` to `Component B, C and F`
6. In the event of an overlapping set of _complementary_ Relationship Definitions, Union.
7. In the event of an overlapping set of conflicting Relationship Definitions:
No relationship type (**Kind**) is inherently more important than the next one, so will not be any case of _conflict_
### Order of Operations (Evaluation)
Relationship DefinitionOperations are evaluated
[draft statements] No relationship type is inherently more important than the next. With that said Hierarchical relationships are evaluated first. No, this is not universally true. What is true is that… drop targets are… upon breach of a join/leave proximity perimeter, an evaluation occurs foremost with respect to the **type** of Relationship being evaluated, which in the case of Edge vs Heirarchical/Sibling things are fairly clear. Although, at some point, all three types of rules will need to be considered simultaneously.
### Relationship Example: Edge-Network
Using the Kubernetes Service as a specific example for which the following Relationship would be registered:
```
name:
apiVersion: core.meshery.io/v1alpha1
kind: Relationship
metadata:
Description: Network edge relationship
name: Network Edge Relationship
type: edge
sub-type: network
selectors:
allow:
from: self
to:
```
* `kind: Pod`
```
model: Kubernetes
```
* `kind: Deployment`
```
model: Kubernetes
```
* `kind: Endpoints`
```
model: Kubernetes
```
Use cases for Edges in the Visualizer:
1. Flow of traffic between services
2. Dependency representation (?)
3. Metrics
4.
Use cases for Edges in Designer:
1. Dependency representation (?)
2. Grouping Components. Eg: As selectors for services, Deployments, etc
1. In this case,an Edge need not be a first class construct, it can just be a way of representing a configuration in the design(selectors of the service in this case)
### RelationshipDefinition Example: Namespaced Kubernetes Components
This Relationship identifies a component as being **parent-capable**. In other words, this Relationship identifies the matching component as being a compound node.
```
apiVersion: core.meshery.io/v1alpha1
kind: RelationshipDefinition
Metadata:
name: Namespaced Kubernetes Component
Description: A Kubernetes component that must belong to a Kubernetes Namespace in order to be instantiated.
type: hierarchical
sub-type: child
selector:
to:
- Kubernetes.Namespace
from:
- self
```
### RelationshipDefinition Example: MeshMap Compound Node
This Relationship identifies a component as being **child-capable**. In other words, this Relationship identifies the matching component as being a compound node.
```
apiVersion: core.meshery.io/v1alpha1
kind: RelationshipDefinition
Metadata:
name: MeshMap Compound Node
Description: A component that is capable of having supporting children and any number of generations of their progeny.
type: hierarchical
sub-type: parent
selector:
allow:
from:
- self
to:
- *
```
\
AttributeDefinition Schema
```
apiVersion: core.meshery.io/v1alpha1
kind: AttributeDefinition
metadata:
componentType: compound-node
selectors:
nonself:
type: namespace
```
### Scoping Relationships
1. Global Scope: The relationships can be configured to be applied to specific model, a specific model version or can be configured to be applied across model. The relationship schema has a `model` and `version` attribute which facilitates this control. Eg: If the model is specified as `aws-ec2-controller`, the relationship will work for those components which belongs to the `aws-ec2-controller` model.
2. Local Scope: It is controlled via the `selectors` attribute in the relationships.
## Policies
* category=security
* type=opa
### Policy Schema
```
apiVersion: core.meshery.io/v1alpha1
kind: PolicyDefinition
metadata:
type: match
sub-type: relationship
selectors:
self:
type: node
nonself:
type: namespace
action:
type: allow
```
### WASM runtime for policy evaluation
Meshmap is a significant component for designing Infrastructure and should provide rich user experience by incorporating real time interactions. Almost every interaction on the canvas can be captured and evaluated to trigger update and enhance UX, but client side validation in vanilla JS is a hindrance and we need to look for alternatives. WASM is one such solution.
As a results there are 2 immediate concerns:
1. On what format OPA policy would work, Pattern file / cytoJSON ?
Motivation for Pattern file:
Pattern file format is at the core of Meshery and Meshmap, it is the format that meshery server understands and almost all operations are invoked on pattern file format itself, it is the only way, how users can share their designs. Every component Meshery interacts with uses pattern file (Adapters / UI clients / catalogs). CytoJSON is only limited to MeshMap and that too only when design is active on the canvas. Any changes in the design are still persisted in the form of a pattern file.
**Concerns:**
1. This will mean when evaluating OPA policies active design (in cyto format) needs to be converted into pattern file and requires a transpilation logic (which will run in WASM runtime). As a result, proper lifecycle management of this WASM runtime is required.
Proper lifecycle management is necessary for all components to ensure proper functioning, system should be self-healing and able to report errors in such situations. WASM runtime will be used for cause other than OPA evaluation also, in such cases as well it should be up and running.
**Policy evaluation flow:**
1. UI (event fired which requires policy evaluation):
I/P format: cytoJSON
Ctx-aware-machine transitions to a state, responsible for converting i/p to correct format.
O/P format: Pattern file
2. I/P format: Pattern file
Ctx aware machine transitions to policy evaluation state and transpiled I/P given to OPA engine and evaluation results are returned.
O/P format: Pattern file (may be modified as a result of evaluation)
3. I/P format: Pattern file
Ctx aware machine again transitions to a state, responsible for converting i/p to correct format.
O/P format: cytoJSON
**Overall result:**
I/P format: CytoJSON
Transpiling layer: WASM runtime
O/P format: Pattern file
Who will evaluate policies ? Meshery server’s OPA evaluation engine / logic OR using OPA’s [NPM package](https://www.npmjs.com/package/@open-policy-agent/opa-wasm).
Areas of use:
1. Designer:
1. Evaluation of OPA policies:
I. Context aware designs which affects component’s config
II. UX enhancements and controlling user actions:. Eg: evaluation which nodes should be highlighted, restricting component on which other component can be dropped / dragged into. Some of these will be a result of evaluation of meshmodel relationship itself.
2. Real time analysis of designs:
3.
Meshery needs to evaluate RelationshipDefinition Policy when: \
1. Import of manifest, charts, compose, designs
1. Meshery Server (pattern file) (for pre-processing)
2. Rendering of design
2. **MeshMap Snapshot (cyto)**
3. Validation of design
3. ~~MeshMap - avjs (schema)~~
4. **Meshery Server (pattern file)**
4. Deployment of design
5. Meshery UI -|
6. MeshMap —— } **Meshery Server (pattern file)**
7. Mesheryctl -|
5. On drag and on drop of nodes and edges on canvas
8. **MeshMap (cyto)**
**Kubernetes | Docker =**
**pattern file **{
service: acme-design
asdfasdf:asdfasd
{traits:},
{spec.pod.image},
}
Jsonpath cyto.pattern.metadata.
**spec.cyto**
{
{metadata: colors, icons},
{spec.pod.image},
}
# Policy Evaluation
### Tiers of Evaluation
#### Tier-1: Client side
_Input: All nodes on canvas and all registered relationships._
_Output: Assigning actions possible with each node on canvas, and animations to invoke. These are meant to enhance the UX and is in context with the current state of Canvas._
The Tier-1 eval results help answer the following queries:
Q1 Set of nodes to highlight.