github.com/oam-dev/kubevela@v1.9.11/references/cli/adopt-templates/default.cue (about)

     1  import (
     2  	"list"
     3  	"strings"
     4  )
     5  
     6  #Resource: {
     7  	apiVersion: string
     8  	kind:       string
     9  	metadata: {
    10  		name:       string
    11  		namespace?: string
    12  		annotations?: [string]: string
    13  		...
    14  	}
    15  	...
    16  }
    17  
    18  #Component: {
    19  	type: string
    20  	name: string
    21  	properties: {...}
    22  	dependsOn?: [...string]
    23  	traits?: [...#Trait]
    24  }
    25  
    26  #Trait: {
    27  	type: string
    28  	properties: {...}
    29  }
    30  
    31  #Policy: {
    32  	type: string
    33  	name: string
    34  	properties?: {...}
    35  }
    36  
    37  #WorkflowStep: {
    38  	type: string
    39  	name: string
    40  	properties?: {...}
    41  	subSteps?: [...{...}]
    42  }
    43  
    44  #Application: {
    45  	apiVersion: "core.oam.dev/v1beta1"
    46  	kind:       "Application"
    47  	metadata: {
    48  		name:       string
    49  		namespace?: string
    50  		labels?: [string]:      string
    51  		annotations?: [string]: string
    52  	}
    53  	spec: {
    54  		components: [...#Component]
    55  		policies?: [...#Policy]
    56  		workflow?: {
    57  			steps: [...#WorkflowStep]
    58  		}
    59  	}
    60  }
    61  
    62  #AdoptOptions: {
    63  	mode:         *"read-only" | "take-over"
    64  	type:         *"native" | "helm" | string
    65  	appName:      string
    66  	appNamespace: string
    67  	resources: [...#Resource]
    68  	...
    69  }
    70  
    71  #Adopt: {
    72  	$args:    #AdoptOptions
    73  	$returns: #Application
    74  
    75  	// adopt logics
    76  
    77  	resourceCategoryMap: {
    78  		crd: ["CustomResourceDefinition"]
    79  		ns: ["Namespace"]
    80  		workload: ["Deployment", "StatefulSet", "DaemonSet", "CloneSet"]
    81  		service: ["Service", "Ingress", "HTTPRoute"]
    82  		config: ["ConfigMap", "Secret"]
    83  		sa: ["ServiceAccount", "Role", "RoleBinding", "ClusterRole", "ClusterRoleBinding"]
    84  		operator: ["MutatingWebhookConfiguration", "ValidatingWebhookConfiguration", "APIService"]
    85  		storage: ["PersistentVolume", "PersistentVolumeClaim"]
    86  	}
    87  
    88  	_resources: [ for r in $args.resources {
    89  		r
    90  		_category: *"unknown" | string
    91  		for key, kinds in resourceCategoryMap if list.Contains(kinds, r.kind) {
    92  			_category: key
    93  		}
    94  		_cluster: *"local" | string
    95  		if r.metadata.labels != _|_ if r.metadata.labels["app.oam.dev/cluster"] != _|_ {
    96  			_cluster: r.metadata.labels["app.oam.dev/cluster"]
    97  		}
    98  	}]
    99  
   100  	_clusters: [ for _cluster, _ in {for r in _resources {"\(r._cluster)": true}} {_cluster}]
   101  
   102  	appName: $args.appName
   103  	clusterEntries: {
   104  		for cluster in _clusters {
   105  			"\(cluster)": {
   106  				_prefix: *"" | string
   107  				if cluster != "local" {
   108  					_prefix: cluster + ":"
   109  				}
   110  				resourceMap: {
   111  					for key, val in resourceCategoryMap {
   112  						"\(key)": [ for r in _resources if r._category == key && r._cluster == cluster {r}]
   113  					}
   114  					unknown: [ for r in _resources if r._category == "unknown" && r._cluster == cluster {r}]
   115  				}
   116  
   117  				unknownKinds: {for r in resourceMap.unknown {"\(r.kind)": true}}
   118  				unknownByKinds: {for kind, val in unknownKinds {
   119  					"\(kind)": [ for r in resourceMap.unknown if r.kind == kind {r}]
   120  				}}
   121  
   122  				comps: [
   123  					if len(resourceMap.crd) > 0 {
   124  						type: "k8s-objects"
   125  						name: "\(_prefix)crds"
   126  						properties: objects: [ for r in resourceMap.crd {
   127  							apiVersion: r.apiVersion
   128  							kind:       r.kind
   129  							metadata: name: r.metadata.name
   130  						}]
   131  					},
   132  					if len(resourceMap.ns) > 0 {
   133  						type: "k8s-objects"
   134  						name: "\(_prefix)ns"
   135  						properties: objects: [ for r in resourceMap.ns {
   136  							apiVersion: r.apiVersion
   137  							kind:       r.kind
   138  							metadata: name: r.metadata.name
   139  						}]
   140  					},
   141  					for r in resourceMap.workload + resourceMap.service {
   142  						type: "k8s-objects"
   143  						name: _prefix + strings.ToLower("\(r.kind)-\(r.metadata.name)")
   144  						properties: objects: [{
   145  							apiVersion: r.apiVersion
   146  							kind:       r.kind
   147  							metadata: name: r.metadata.name
   148  							if r.metadata.namespace != _|_ {
   149  								metadata: namespace: r.metadata.namespace
   150  							}
   151  							spec: r.spec
   152  						}]
   153  					},
   154  					for key in ["config", "sa", "operator", "storage"] if len(resourceMap[key]) > 0 {
   155  						type: "k8s-objects"
   156  						name: "\(_prefix)\(key)"
   157  						properties: objects: [ for r in resourceMap[key] {
   158  							apiVersion: r.apiVersion
   159  							kind:       r.kind
   160  							metadata: name: r.metadata.name
   161  							if r.metadata.namespace != _|_ {
   162  								metadata: namespace: r.metadata.namespace
   163  							}
   164  						}]
   165  					},
   166  					for kind, rs in unknownByKinds {
   167  						type: "k8s-objects"
   168  						name: "\(_prefix)\(kind)"
   169  						properties: objects: [ for r in rs {
   170  							apiVersion: r.apiVersion
   171  							kind:       r.kind
   172  							metadata: name: r.metadata.name
   173  							if r.metadata.namespace != _|_ {
   174  								metadata: namespace: r.metadata.namespace
   175  							}
   176  						}]
   177  					},
   178  				]
   179  			}
   180  		}
   181  	}
   182  
   183  	$returns: #Application & {
   184  		metadata: {
   185  			name:      $args.appName
   186  			namespace: $args.appNamespace
   187  			labels: "app.oam.dev/adopt": $args.type
   188  		}
   189  		spec: components: [ for cluster, entry in clusterEntries for comp in entry.comps {comp}]
   190  		spec: policies: [
   191  			{
   192  				type: $args.mode
   193  				name: $args.mode
   194  				properties: rules: [{
   195  					selector: componentNames: [ for comp in spec.components {comp.name}]
   196  				}]
   197  			},
   198  			if $args.mode == "take-over" {
   199  				type: "garbage-collect"
   200  				name: "garbage-collect"
   201  				properties: rules: [{
   202  					strategy: "never"
   203  					selector: resourceTypes: ["CustomResourceDefinition"]
   204  				}]
   205  			},
   206  			if $args.mode == "take-over" {
   207  				type: "apply-once"
   208  				name: "apply-once"
   209  				properties: rules: [{
   210  					selector: resourceTypes: ["CustomResourceDefinition"]
   211  				}]
   212  			}]
   213  		spec: workflow: steps: [{
   214  			type: "step-group"
   215  			name: "apply-component"
   216  			subSteps: [ for c, entry in clusterEntries for comp in entry.comps {
   217  				type: "apply-component"
   218  				name: "apply-component:" + comp.name
   219  				properties: component: comp.name
   220  				if c != "local" {
   221  					properties: cluster: c
   222  				}
   223  			}]
   224  		}]
   225  	}
   226  }