github.com/rancher/types@v0.0.0-20220328215343-4370ff10ecd5/apis/project.cattle.io/v3/schema/schema.go (about)

     1  package schema
     2  
     3  import (
     4  	"net/http"
     5  
     6  	monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
     7  	istiov1alpha3 "github.com/knative/pkg/apis/istio/v1alpha3"
     8  	"github.com/rancher/norman/types"
     9  	m "github.com/rancher/norman/types/mapper"
    10  	v3 "github.com/rancher/types/apis/project.cattle.io/v3"
    11  	"github.com/rancher/types/factory"
    12  	"github.com/rancher/types/mapper"
    13  	appsv1 "k8s.io/api/apps/v1"
    14  	k8sappv1 "k8s.io/api/apps/v1"
    15  	autoscaling "k8s.io/api/autoscaling/v2beta2"
    16  	batchv1 "k8s.io/api/batch/v1"
    17  	batchv1beta1 "k8s.io/api/batch/v1beta1"
    18  	v1 "k8s.io/api/core/v1"
    19  	"k8s.io/api/extensions/v1beta1"
    20  )
    21  
    22  var (
    23  	Version = types.APIVersion{
    24  		Version:          "v3",
    25  		Group:            "project.cattle.io",
    26  		Path:             "/v3/project",
    27  		SubContext:       true,
    28  		SubContextSchema: "/v3/schemas/project",
    29  	}
    30  
    31  	Schemas = factory.Schemas(&Version).
    32  		// volume before pod types.  pod types uses volume things, so need to register mapper
    33  		Init(volumeTypes).
    34  		Init(configMapTypes).
    35  		Init(ingressTypes).
    36  		Init(secretTypes).
    37  		Init(serviceTypes).
    38  		Init(podTypes).
    39  		Init(deploymentTypes).
    40  		Init(replicationControllerTypes).
    41  		Init(replicaSetTypes).
    42  		Init(statefulSetTypes).
    43  		Init(daemonSetTypes).
    44  		Init(jobTypes).
    45  		Init(cronJobTypes).
    46  		Init(podTemplateSpecTypes).
    47  		Init(workloadTypes).
    48  		Init(appTypes).
    49  		Init(pipelineTypes).
    50  		Init(monitoringTypes).
    51  		Init(autoscalingTypes).
    52  		Init(istioTypes)
    53  )
    54  
    55  func configMapTypes(schemas *types.Schemas) *types.Schemas {
    56  	return schemas.MustImportAndCustomize(&Version, v1.ConfigMap{}, func(schema *types.Schema) {
    57  		schema.MustCustomizeField("name", func(field types.Field) types.Field {
    58  			field.Type = "hostname"
    59  			field.Nullable = false
    60  			field.Required = true
    61  			return field
    62  		})
    63  	}, projectOverride{})
    64  }
    65  
    66  type DeploymentConfig struct {
    67  }
    68  
    69  type StatefulSetConfig struct {
    70  }
    71  
    72  type ReplicaSetConfig struct {
    73  }
    74  
    75  type ReplicationControllerConfig struct {
    76  }
    77  
    78  type DaemonSetConfig struct {
    79  }
    80  
    81  type CronJobConfig struct {
    82  }
    83  
    84  type JobConfig struct {
    85  }
    86  
    87  type deploymentConfigOverride struct {
    88  	DeploymentConfig DeploymentConfig
    89  }
    90  
    91  type statefulSetConfigOverride struct {
    92  	StatefulSetConfig StatefulSetConfig
    93  }
    94  
    95  type replicaSetConfigOverride struct {
    96  	ReplicaSetConfig ReplicaSetConfig
    97  }
    98  
    99  type replicationControllerConfigOverride struct {
   100  	ReplicationControllerConfig ReplicationControllerConfig
   101  }
   102  
   103  type daemonSetOverride struct {
   104  	DaemonSetConfig DaemonSetConfig
   105  }
   106  
   107  type cronJobOverride struct {
   108  	CronJobConfig CronJobConfig
   109  }
   110  
   111  type jobOverride struct {
   112  	JobConfig JobConfig
   113  }
   114  
   115  func workloadTypes(schemas *types.Schemas) *types.Schemas {
   116  	return schemas.MustImportAndCustomize(&Version, v3.Workload{},
   117  		func(schema *types.Schema) {
   118  			toInclude := []string{"deployment", "replicationController", "statefulSet",
   119  				"daemonSet", "job", "cronJob", "replicaSet"}
   120  			for _, name := range toInclude {
   121  				baseSchema := schemas.Schema(&Version, name)
   122  				if baseSchema == nil {
   123  					continue
   124  				}
   125  				for name, field := range baseSchema.ResourceFields {
   126  					schema.ResourceFields[name] = field
   127  				}
   128  			}
   129  			schema.ResourceActions = map[string]types.Action{
   130  				"rollback": {
   131  					Input: "rollbackRevision",
   132  				},
   133  				"pause":    {},
   134  				"resume":   {},
   135  				"redeploy": {},
   136  			}
   137  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   138  				field.Type = "dnsLabelRestricted"
   139  				field.Nullable = false
   140  				field.Required = true
   141  				return field
   142  			})
   143  		})
   144  }
   145  
   146  func statefulSetTypes(schemas *types.Schemas) *types.Schemas {
   147  	return schemas.
   148  		AddMapperForType(&Version, k8sappv1.StatefulSetUpdateStrategy{},
   149  			&m.Embed{Field: "rollingUpdate"},
   150  			m.Enum{Field: "type", Options: []string{
   151  				"RollingUpdate",
   152  				"OnDelete",
   153  			}},
   154  			m.Move{From: "type", To: "strategy"},
   155  		).
   156  		AddMapperForType(&Version, k8sappv1.StatefulSetSpec{},
   157  			&m.Move{
   158  				From: "replicas",
   159  				To:   "scale",
   160  			},
   161  			&m.Embed{Field: "updateStrategy"},
   162  			&m.Enum{
   163  				Field: "podManagementPolicy",
   164  				Options: []string{
   165  					"OrderedReady",
   166  					"Parallel",
   167  				},
   168  			},
   169  			&m.BatchMove{
   170  				From: []string{
   171  					"partition",
   172  					"strategy",
   173  					"volumeClaimTemplates",
   174  					"serviceName",
   175  					"revisionHistoryLimit",
   176  					"podManagementPolicy",
   177  				},
   178  				To: "statefulSetConfig",
   179  			},
   180  			&m.Embed{Field: "template"},
   181  		).
   182  		MustImport(&Version, v3.WorkloadMetric{}).
   183  		AddMapperForType(&Version, k8sappv1.StatefulSet{},
   184  			&m.Move{
   185  				From: "status",
   186  				To:   "statefulSetStatus",
   187  			},
   188  			NewWorkloadTypeMapper(),
   189  		).
   190  		MustImport(&Version, k8sappv1.StatefulSetSpec{}, statefulSetConfigOverride{}).
   191  		MustImportAndCustomize(&Version, k8sappv1.StatefulSet{}, func(schema *types.Schema) {
   192  			schema.BaseType = "workload"
   193  			schema.ResourceActions = map[string]types.Action{
   194  				"redeploy": {},
   195  			}
   196  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   197  				field.Type = "dnsLabelRestricted"
   198  				field.Nullable = false
   199  				field.Required = true
   200  				return field
   201  			})
   202  		}, projectOverride{}, struct {
   203  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   204  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"`
   205  		}{})
   206  }
   207  
   208  func replicaSetTypes(schemas *types.Schemas) *types.Schemas {
   209  	return schemas.
   210  		AddMapperForType(&Version, appsv1.ReplicaSetSpec{},
   211  			&m.Move{
   212  				From: "replicas",
   213  				To:   "scale",
   214  			},
   215  			&m.Move{
   216  				From: "minReadySeconds",
   217  				To:   "replicaSetConfig/minReadySeconds",
   218  			},
   219  		).
   220  		MustImport(&Version, v3.WorkloadMetric{}).
   221  		AddMapperForType(&Version, appsv1.ReplicaSet{},
   222  			&m.Move{
   223  				From: "status",
   224  				To:   "replicaSetStatus",
   225  			},
   226  			&m.Embed{Field: "template"},
   227  			NewWorkloadTypeMapper(),
   228  		).
   229  		MustImport(&Version, appsv1.ReplicaSetSpec{}, replicaSetConfigOverride{}).
   230  		MustImportAndCustomize(&Version, appsv1.ReplicaSet{}, func(schema *types.Schema) {
   231  			schema.BaseType = "workload"
   232  			schema.ResourceActions = map[string]types.Action{
   233  				"redeploy": {},
   234  			}
   235  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   236  				field.Type = "dnsLabelRestricted"
   237  				field.Nullable = false
   238  				field.Required = true
   239  				return field
   240  			})
   241  		}, projectOverride{}, struct {
   242  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   243  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"`
   244  		}{})
   245  }
   246  
   247  func replicationControllerTypes(schemas *types.Schemas) *types.Schemas {
   248  	return schemas.
   249  		AddMapperForType(&Version, v1.ReplicationControllerSpec{},
   250  			&m.Move{
   251  				From: "replicas",
   252  				To:   "scale",
   253  			},
   254  			&m.Move{
   255  				From: "minReadySeconds",
   256  				To:   "replicationControllerConfig/minReadySeconds",
   257  			},
   258  			&m.Embed{Field: "template"},
   259  		).
   260  		MustImport(&Version, v3.WorkloadMetric{}).
   261  		AddMapperForType(&Version, v1.ReplicationController{},
   262  			&m.Move{
   263  				From: "status",
   264  				To:   "replicationControllerStatus",
   265  			},
   266  			NewWorkloadTypeMapper(),
   267  		).
   268  		MustImport(&Version, v1.ReplicationControllerSpec{}, replicationControllerConfigOverride{}).
   269  		MustImportAndCustomize(&Version, v1.ReplicationController{}, func(schema *types.Schema) {
   270  			schema.BaseType = "workload"
   271  			schema.CollectionMethods = []string{http.MethodGet}
   272  			schema.ResourceMethods = []string{http.MethodGet}
   273  			schema.ResourceActions = map[string]types.Action{
   274  				"redeploy": {},
   275  			}
   276  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   277  				field.Type = "dnsLabelRestricted"
   278  				field.Nullable = false
   279  				field.Required = true
   280  				return field
   281  			})
   282  		}, projectOverride{}, struct {
   283  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   284  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"`
   285  		}{})
   286  }
   287  
   288  func daemonSetTypes(schemas *types.Schemas) *types.Schemas {
   289  	return schemas.
   290  		AddMapperForType(&Version, k8sappv1.DaemonSetUpdateStrategy{},
   291  			&m.Embed{Field: "rollingUpdate"},
   292  			m.Enum{Field: "type", Options: []string{
   293  				"RollingUpdate",
   294  				"OnDelete",
   295  			}},
   296  			m.Move{From: "type", To: "strategy"},
   297  		).
   298  		AddMapperForType(&Version, k8sappv1.DaemonSetSpec{},
   299  			&m.Embed{Field: "updateStrategy"},
   300  			&m.BatchMove{
   301  				From: []string{
   302  					"strategy",
   303  					"maxUnavailable",
   304  					"minReadySeconds",
   305  					"revisionHistoryLimit",
   306  				},
   307  				To: "daemonSetConfig",
   308  			},
   309  			&m.Embed{Field: "template"},
   310  		).
   311  		MustImport(&Version, v3.WorkloadMetric{}).
   312  		AddMapperForType(&Version, k8sappv1.DaemonSet{},
   313  			&m.Move{
   314  				From: "status",
   315  				To:   "daemonSetStatus",
   316  			},
   317  			NewWorkloadTypeMapper(),
   318  		).
   319  		MustImport(&Version, k8sappv1.DaemonSetSpec{}, daemonSetOverride{}).
   320  		MustImportAndCustomize(&Version, k8sappv1.DaemonSet{}, func(schema *types.Schema) {
   321  			schema.BaseType = "workload"
   322  			schema.ResourceActions = map[string]types.Action{
   323  				"redeploy": {},
   324  			}
   325  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   326  				field.Type = "dnsLabelRestricted"
   327  				field.Nullable = false
   328  				field.Required = true
   329  				return field
   330  			})
   331  		}, projectOverride{}, struct {
   332  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   333  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"`
   334  		}{})
   335  }
   336  
   337  func jobTypes(schemas *types.Schemas) *types.Schemas {
   338  	return schemas.
   339  		AddMapperForType(&Version, batchv1.JobSpec{},
   340  			&m.BatchMove{
   341  				From: []string{"parallelism",
   342  					"completions",
   343  					"activeDeadlineSeconds",
   344  					"backoffLimit",
   345  					"manualSelector",
   346  				},
   347  				To: "jobConfig",
   348  			},
   349  			&m.Embed{Field: "template"},
   350  		).
   351  		MustImport(&Version, v3.WorkloadMetric{}).
   352  		AddMapperForType(&Version, batchv1.Job{},
   353  			&m.Move{
   354  				From: "status",
   355  				To:   "jobStatus",
   356  			},
   357  			NewWorkloadTypeMapper(),
   358  		).
   359  		MustImport(&Version, batchv1.JobSpec{}, jobOverride{}).
   360  		MustImportAndCustomize(&Version, batchv1.Job{}, func(schema *types.Schema) {
   361  			schema.BaseType = "workload"
   362  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   363  				field.Type = "dnsLabelRestricted"
   364  				field.Nullable = false
   365  				field.Required = true
   366  				return field
   367  			})
   368  		}, projectOverride{}, struct {
   369  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   370  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"`
   371  		}{})
   372  }
   373  
   374  func cronJobTypes(schemas *types.Schemas) *types.Schemas {
   375  	return schemas.
   376  		AddMapperForType(&Version, batchv1beta1.JobTemplateSpec{},
   377  			&m.Move{
   378  				From: "metadata",
   379  				To:   "jobMetadata",
   380  			},
   381  			&m.Embed{Field: "spec"},
   382  		).
   383  		AddMapperForType(&Version, batchv1beta1.CronJobSpec{},
   384  			&m.Embed{
   385  				Field: "jobTemplate",
   386  			},
   387  			&m.BatchMove{
   388  				From: []string{
   389  					"schedule",
   390  					"startingDeadlineSeconds",
   391  					"suspend",
   392  					"successfulJobsHistoryLimit",
   393  					"failedJobsHistoryLimit",
   394  					"jobConfig",
   395  				},
   396  				To: "cronJobConfig",
   397  			},
   398  			&m.Enum{Field: "concurrencyPolicy", Options: []string{
   399  				"Allow",
   400  				"Forbid",
   401  				"Replace",
   402  			}},
   403  			&m.Move{
   404  				From: "concurrencyPolicy",
   405  				To:   "cronJobConfig/concurrencyPolicy",
   406  			},
   407  			&m.Move{
   408  				From:              "jobMetadata/labels",
   409  				To:                "cronJobConfig/jobLabels",
   410  				NoDeleteFromField: true,
   411  			},
   412  			&m.Move{
   413  				From:              "jobMetadata/annotations",
   414  				To:                "cronJobConfig/jobAnnotations",
   415  				NoDeleteFromField: true,
   416  			},
   417  			&m.Drop{Field: "jobMetadata"},
   418  		).
   419  		MustImport(&Version, v3.WorkloadMetric{}).
   420  		AddMapperForType(&Version, batchv1beta1.CronJob{},
   421  			&m.Move{
   422  				From: "status",
   423  				To:   "cronJobStatus",
   424  			},
   425  			NewWorkloadTypeMapper(),
   426  		).
   427  		MustImport(&Version, batchv1beta1.CronJobSpec{}, cronJobOverride{}).
   428  		MustImport(&Version, batchv1beta1.JobTemplateSpec{}).
   429  		MustImportAndCustomize(&Version, batchv1beta1.CronJob{}, func(schema *types.Schema) {
   430  			schema.BaseType = "workload"
   431  			schema.ResourceActions = map[string]types.Action{
   432  				"redeploy": {},
   433  			}
   434  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   435  				field.Type = "dnsLabelRestricted"
   436  				field.Nullable = false
   437  				field.Required = true
   438  				return field
   439  			})
   440  		}, projectOverride{}, struct {
   441  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   442  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"`
   443  		}{})
   444  }
   445  
   446  func deploymentTypes(schemas *types.Schemas) *types.Schemas {
   447  	return schemas.
   448  		AddMapperForType(&Version, k8sappv1.DeploymentStrategy{},
   449  			&m.Embed{Field: "rollingUpdate", EmptyValueOk: true},
   450  			m.Enum{Field: "type", Options: []string{
   451  				"Recreate",
   452  				"RollingUpdate",
   453  			}},
   454  			m.Move{From: "type", To: "strategy"},
   455  		).
   456  		AddMapperForType(&Version, k8sappv1.DeploymentSpec{},
   457  			&m.Move{
   458  				From: "strategy",
   459  				To:   "upgradeStrategy",
   460  			},
   461  			&m.Embed{Field: "upgradeStrategy"},
   462  			&m.Move{
   463  				From: "replicas",
   464  				To:   "scale",
   465  			},
   466  			&m.BatchMove{
   467  				From: []string{
   468  					"minReadySeconds",
   469  					"strategy",
   470  					"revisionHistoryLimit",
   471  					"progressDeadlineSeconds",
   472  					"maxUnavailable",
   473  					"maxSurge",
   474  				},
   475  				To: "deploymentConfig",
   476  			},
   477  			&m.Embed{Field: "template"},
   478  		).
   479  		MustImport(&Version, v3.WorkloadMetric{}).
   480  		AddMapperForType(&Version, k8sappv1.Deployment{},
   481  			&m.Move{
   482  				From: "status",
   483  				To:   "deploymentStatus",
   484  			},
   485  			NewWorkloadTypeMapper(),
   486  		).
   487  		MustImport(&Version, k8sappv1.DeploymentSpec{}, deploymentConfigOverride{}).
   488  		MustImport(&Version, v3.DeploymentRollbackInput{}).
   489  		MustImportAndCustomize(&Version, k8sappv1.Deployment{}, func(schema *types.Schema) {
   490  			schema.BaseType = "workload"
   491  			schema.ResourceActions = map[string]types.Action{
   492  				"rollback": {
   493  					Input: "deploymentRollbackInput",
   494  				},
   495  				"pause":    {},
   496  				"resume":   {},
   497  				"redeploy": {},
   498  			}
   499  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   500  				field.Type = "dnsLabelRestricted"
   501  				field.Nullable = false
   502  				field.Required = true
   503  				return field
   504  			})
   505  		}, projectOverride{}, struct {
   506  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   507  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"`
   508  		}{})
   509  }
   510  
   511  func podTypes(schemas *types.Schemas) *types.Schemas {
   512  	return schemas.
   513  		AddMapperForType(&Version, v1.PodTemplateSpec{},
   514  			&m.Embed{Field: "spec"},
   515  		).
   516  		AddMapperForType(&Version, v1.Capabilities{},
   517  			m.Move{From: "add", To: "capAdd"},
   518  			m.Move{From: "drop", To: "capDrop"},
   519  		).
   520  		AddMapperForType(&Version, v1.PodSecurityContext{},
   521  			m.Drop{Field: "seLinuxOptions"},
   522  			m.Move{From: "runAsUser", To: "uid"},
   523  			m.Move{From: "supplementalGroups", To: "gids"},
   524  			m.Move{From: "fsGroup", To: "fsgid"},
   525  		).
   526  		AddMapperForType(&Version, v1.SecurityContext{},
   527  			&m.Embed{Field: "capabilities"},
   528  			m.Drop{Field: "seLinuxOptions"},
   529  			m.Move{From: "readOnlyRootFilesystem", To: "readOnly"},
   530  			m.Move{From: "runAsUser", To: "uid"},
   531  		).
   532  		AddMapperForType(&Version, v1.Container{},
   533  			m.Move{From: "command", To: "entrypoint"},
   534  			m.Move{From: "args", To: "command"},
   535  			mapper.EnvironmentMapper{},
   536  			&m.Embed{Field: "securityContext"},
   537  			&m.Embed{Field: "lifecycle"},
   538  		).
   539  		AddMapperForType(&Version, v1.ContainerPort{},
   540  			m.Move{From: "hostIP", To: "hostIp"},
   541  		).
   542  		AddMapperForType(&Version, v1.Handler{},
   543  			mapper.ContainerProbeHandler{}).
   544  		AddMapperForType(&Version, v1.Probe{}, mapper.ContainerProbeHandler{}).
   545  		AddMapperForType(&Version, v1.Handler{}, handlerMapper).
   546  		AddMapperForType(&Version, v1.Probe{}, handlerMapper).
   547  		AddMapperForType(&Version, v1.PodStatus{},
   548  			m.Move{From: "hostIP", To: "nodeIp"},
   549  			m.Move{From: "podIP", To: "podIp"},
   550  		).
   551  		AddMapperForType(&Version, v1.PodSpec{},
   552  			mapper.InitContainerMapper{},
   553  			mapper.SchedulingMapper{},
   554  			m.Move{From: "priority", To: "scheduling/priority", DestDefined: true},
   555  			m.Move{From: "priorityClassName", To: "scheduling/priorityClassName", DestDefined: true},
   556  			m.Move{From: "schedulerName", To: "scheduling/scheduler", DestDefined: true},
   557  			m.Move{From: "tolerations", To: "scheduling/tolerate", DestDefined: true},
   558  			&m.Embed{Field: "securityContext"},
   559  			&m.Drop{Field: "serviceAccount"},
   560  		).
   561  		AddMapperForType(&Version, v1.Pod{},
   562  			&m.AnnotationField{Field: "description"},
   563  			&m.AnnotationField{Field: "publicEndpoints", List: true},
   564  			&m.AnnotationField{Field: "workloadMetrics", List: true},
   565  			mapper.ContainerPorts{},
   566  			mapper.ContainerStatus{},
   567  		).
   568  		// Must import handlers before Container
   569  		MustImport(&Version, v1.ContainerPort{}, struct {
   570  			Kind       string `json:"kind,omitempty" norman:"type=enum,options=HostPort|NodePort|ClusterIP|LoadBalancer"`
   571  			SourcePort int    `json:"sourcePort,omitempty"`
   572  			DNSName    string `json:"dnsName,omitempty"`
   573  			Name       string `json:"name,omitempty"`
   574  			Protocol   string `json:"protocol,omitempty"`
   575  		}{}).
   576  		MustImport(&Version, v1.Capabilities{}, struct {
   577  			Add  []string `norman:"type=array[enum],options=AUDIT_CONTROL|AUDIT_WRITE|BLOCK_SUSPEND|CHOWN|DAC_OVERRIDE|DAC_READ_SEARCH|FOWNER|FSETID|IPC_LOCK|IPC_OWNER|KILL|LEASE|LINUX_IMMUTABLE|MAC_ADMIN|MAC_OVERRIDE|MKNOD|NET_ADMIN|NET_BIND_SERVICE|NET_BROADCAST|NET_RAW|SETFCAP|SETGID|SETPCAP|SETUID|SYSLOG|SYS_ADMIN|SYS_BOOT|SYS_CHROOT|SYS_MODULE|SYS_NICE|SYS_PACCT|SYS_PTRACE|SYS_RAWIO|SYS_RESOURCE|SYS_TIME|SYS_TTY_CONFIG|WAKE_ALARM|ALL"`
   578  			Drop []string `norman:"type=array[enum],options=AUDIT_CONTROL|AUDIT_WRITE|BLOCK_SUSPEND|CHOWN|DAC_OVERRIDE|DAC_READ_SEARCH|FOWNER|FSETID|IPC_LOCK|IPC_OWNER|KILL|LEASE|LINUX_IMMUTABLE|MAC_ADMIN|MAC_OVERRIDE|MKNOD|NET_ADMIN|NET_BIND_SERVICE|NET_BROADCAST|NET_RAW|SETFCAP|SETGID|SETPCAP|SETUID|SYSLOG|SYS_ADMIN|SYS_BOOT|SYS_CHROOT|SYS_MODULE|SYS_NICE|SYS_PACCT|SYS_PTRACE|SYS_RAWIO|SYS_RESOURCE|SYS_TIME|SYS_TTY_CONFIG|WAKE_ALARM|ALL"`
   579  		}{}).
   580  		MustImport(&Version, v3.PublicEndpoint{}).
   581  		MustImport(&Version, v3.WorkloadMetric{}).
   582  		MustImport(&Version, v1.Handler{}, handlerOverride{}).
   583  		MustImport(&Version, v1.Probe{}, handlerOverride{}).
   584  		MustImport(&Version, v1.Container{}, struct {
   585  			Environment          map[string]string
   586  			EnvironmentFrom      []EnvironmentFrom
   587  			InitContainer        bool
   588  			State                string
   589  			Transitioning        string
   590  			TransitioningMessage string
   591  			ExitCode             *int
   592  			RestartCount         int
   593  		}{}).
   594  		MustImport(&Version, v1.PodSpec{}, struct {
   595  			Scheduling *Scheduling
   596  			NodeName   string `norman:"type=reference[/v3/schemas/node]"`
   597  		}{}).
   598  		MustImport(&Version, v1.Pod{}, projectOverride{}, struct {
   599  			Description     string `json:"description"`
   600  			WorkloadID      string `norman:"type=reference[workload]"`
   601  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   602  			WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric],nocreate,noupdate"`
   603  		}{})
   604  }
   605  
   606  func serviceTypes(schemas *types.Schemas) *types.Schemas {
   607  	return schemas.
   608  		Init(addServiceType).
   609  		Init(addDNSRecord)
   610  }
   611  
   612  func addServiceType(schemas *types.Schemas) *types.Schemas {
   613  	return schemas.AddSchema(*factory.Schemas(&Version).
   614  		Init(addServiceOrDNSRecord(false)).
   615  		Schema(&Version, "service"))
   616  }
   617  
   618  func addDNSRecord(schemas *types.Schemas) *types.Schemas {
   619  	return schemas.
   620  		Init(addServiceOrDNSRecord(true))
   621  }
   622  
   623  func addServiceOrDNSRecord(dns bool) types.SchemasInitFunc {
   624  	return func(schemas *types.Schemas) *types.Schemas {
   625  		if dns {
   626  			schemas = schemas.
   627  				TypeName("dnsRecord", v1.Service{})
   628  		}
   629  
   630  		schemas = schemas.
   631  			AddMapperForType(&Version, v1.ServiceSpec{},
   632  				&m.Move{From: "externalName", To: "hostname"},
   633  				&m.Move{From: "type", To: "serviceKind"},
   634  				&m.SetValue{
   635  					Field: "clusterIP",
   636  					IfEq:  "None",
   637  					Value: nil,
   638  				},
   639  				&m.Move{From: "clusterIP", To: "clusterIp"},
   640  			).
   641  			AddMapperForType(&Version, v1.Service{},
   642  				&m.Drop{Field: "status"},
   643  				&m.LabelField{Field: "workloadId"},
   644  				&m.AnnotationField{Field: "description"},
   645  				&m.AnnotationField{Field: "ipAddresses", List: true},
   646  				&m.AnnotationField{Field: "targetWorkloadIds", List: true},
   647  				&m.AnnotationField{Field: "targetDnsRecordIds", List: true},
   648  				&m.AnnotationField{Field: "publicEndpoints", List: true},
   649  				&m.Move{From: "serviceKind", To: "kind"},
   650  			)
   651  
   652  		if dns {
   653  			schemas = schemas.
   654  				AddMapperForType(&Version, v1.Service{},
   655  					&m.Drop{Field: "kind"},
   656  					&m.Drop{Field: "externalIPs"},
   657  					&m.Drop{Field: "externalTrafficPolicy"},
   658  					&m.Drop{Field: "healthCheckNodePort"},
   659  					&m.Drop{Field: "loadBalancerIP"},
   660  					&m.Drop{Field: "loadBalancerSourceRanges"},
   661  					&m.Drop{Field: "publishNotReadyAddresses"},
   662  					&m.Drop{Field: "sessionAffinity"},
   663  					&m.Drop{Field: "sessionAffinityConfig"},
   664  				)
   665  		}
   666  
   667  		return schemas.MustImportAndCustomize(&Version, v1.Service{}, func(schema *types.Schema) {
   668  			if dns {
   669  				schema.CodeName = "DNSRecord"
   670  				schema.MustCustomizeField("clusterIp", func(f types.Field) types.Field {
   671  					f.Create = false
   672  					f.Update = false
   673  					return f
   674  				})
   675  				schema.MustCustomizeField("ports", func(f types.Field) types.Field {
   676  					f.Create = false
   677  					f.Update = false
   678  					return f
   679  				})
   680  				schema.MustCustomizeField("name", func(field types.Field) types.Field {
   681  					field.Type = "dnsLabelRestricted"
   682  					field.Nullable = false
   683  					field.Required = true
   684  					return field
   685  				})
   686  			}
   687  		}, projectOverride{}, struct {
   688  			Description        string   `json:"description"`
   689  			IPAddresses        []string `json:"ipAddresses"`
   690  			WorkloadID         string   `json:"workloadId" norman:"type=reference[workload],nocreate,noupdate"`
   691  			TargetWorkloadIDs  string   `json:"targetWorkloadIds" norman:"type=array[reference[workload]]"`
   692  			TargetDNSRecordIDs string   `json:"targetDnsRecordIds" norman:"type=array[reference[dnsRecord]]"`
   693  			PublicEndpoints    string   `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   694  		}{})
   695  	}
   696  }
   697  
   698  func ingressTypes(schemas *types.Schemas) *types.Schemas {
   699  	return schemas.
   700  		AddMapperForType(&Version, v1beta1.HTTPIngressPath{},
   701  			&m.Embed{Field: "backend"},
   702  		).
   703  		AddMapperForType(&Version, v1beta1.IngressRule{},
   704  			&m.Embed{Field: "http"},
   705  		).
   706  		AddMapperForType(&Version, v1beta1.Ingress{},
   707  			&m.AnnotationField{Field: "description"},
   708  			&m.Move{From: "backend", To: "defaultBackend"},
   709  			&m.AnnotationField{Field: "publicEndpoints", List: true},
   710  		).
   711  		AddMapperForType(&Version, v1beta1.IngressTLS{},
   712  			&m.Move{From: "secretName", To: "certificateName"},
   713  		).
   714  		AddMapperForType(&Version, v1beta1.IngressBackend{},
   715  			&m.Move{From: "servicePort", To: "targetPort"},
   716  		).
   717  		MustImport(&Version, v1beta1.IngressBackend{}, struct {
   718  			WorkloadIDs string `json:"workloadIds" norman:"type=array[reference[workload]]"`
   719  			ServiceName string `norman:"type=reference[service]"`
   720  		}{}).
   721  		MustImport(&Version, v1beta1.IngressRule{}).
   722  		MustImport(&Version, v1beta1.IngressTLS{}, struct {
   723  			SecretName string `norman:"type=reference[certificate]"`
   724  		}{}).
   725  		MustImportAndCustomize(&Version, v1beta1.Ingress{}, func(schema *types.Schema) {
   726  			schema.MustCustomizeField("name", func(f types.Field) types.Field {
   727  				f.Type = "hostname"
   728  				f.Required = true
   729  				f.Nullable = false
   730  				return f
   731  			})
   732  		}, projectOverride{}, struct {
   733  			Description     string `json:"description"`
   734  			PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"`
   735  		}{})
   736  }
   737  
   738  func volumeTypes(schemas *types.Schemas) *types.Schemas {
   739  	return schemas.
   740  		AddMapperForType(&Version, v1.HostPathVolumeSource{},
   741  			m.Move{From: "type", To: "kind"},
   742  			m.Enum{
   743  				Options: []string{
   744  					"DirectoryOrCreate",
   745  					"Directory",
   746  					"FileOrCreate",
   747  					"File",
   748  					"Socket",
   749  					"CharDevice",
   750  					"BlockDevice",
   751  				},
   752  				Field: "kind",
   753  			},
   754  		).
   755  		AddMapperForType(&Version, v1.PersistentVolumeClaimVolumeSource{},
   756  			&m.Move{From: "claimName", To: "persistentVolumeClaimName"},
   757  		).
   758  		AddMapperForType(&Version, v1.VolumeMount{},
   759  			m.Required{Fields: []string{
   760  				"mountPath",
   761  				"name",
   762  			}},
   763  		).
   764  		AddMapperForType(&Version, v1.PersistentVolumeClaim{},
   765  			mapper.PersistVolumeClaim{},
   766  		).
   767  		MustImport(&Version, v1.PersistentVolumeClaimVolumeSource{}, struct {
   768  			ClaimName string `norman:"type=reference[persistentVolumeClaim]"`
   769  		}{}).
   770  		MustImport(&Version, v1.SecretVolumeSource{}, struct {
   771  		}{}).
   772  		MustImport(&Version, v1.VolumeMount{}, struct {
   773  			MountPath string `json:"mountPath" norman:"required"`
   774  		}{}).
   775  		MustImport(&Version, v1.Volume{}, struct {
   776  		}{}).
   777  		MustImport(&Version, v1.PersistentVolumeSpec{}, struct {
   778  			StorageClassName *string `json:"storageClassName,omitempty" norman:"type=reference[/v3/cluster/storageClass]"`
   779  		}{}).
   780  		MustImport(&Version, v1.PersistentVolumeClaimSpec{}, struct {
   781  			AccessModes      []string `json:"accessModes,omitempty" norman:"type=array[enum],options=ReadWriteOnce|ReadOnlyMany|ReadWriteMany"`
   782  			VolumeName       string   `json:"volumeName,omitempty" norman:"type=reference[/v3/cluster/persistentVolume]"`
   783  			StorageClassName *string  `json:"storageClassName,omitempty" norman:"type=reference[/v3/cluster/storageClass]"`
   784  		}{}).
   785  		MustImportAndCustomize(&Version, v1.PersistentVolumeClaim{}, func(schema *types.Schema) {
   786  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
   787  				field.Type = "hostname"
   788  				field.Nullable = false
   789  				field.Required = true
   790  				return field
   791  			})
   792  		}, projectOverride{})
   793  }
   794  
   795  func appTypes(schema *types.Schemas) *types.Schemas {
   796  	return schema.
   797  		AddMapperForType(&Version, v3.App{}, &m.Embed{Field: "status"}).
   798  		MustImport(&Version, v3.AppUpgradeConfig{}).
   799  		MustImport(&Version, v3.RollbackRevision{}).
   800  		MustImportAndCustomize(&Version, v3.App{}, func(schema *types.Schema) {
   801  			schema.ResourceActions = map[string]types.Action{
   802  				"upgrade": {
   803  					Input: "appUpgradeConfig",
   804  				},
   805  				"rollback": {
   806  					Input: "rollbackRevision",
   807  				},
   808  			}
   809  		}).
   810  		MustImport(&Version, v3.AppRevision{})
   811  }
   812  
   813  func podTemplateSpecTypes(schemas *types.Schemas) *types.Schemas {
   814  	return schemas.
   815  		MustImport(&Version, v1.PodTemplateSpec{})
   816  }
   817  
   818  func NewWorkloadTypeMapper() types.Mapper {
   819  	return &types.Mappers{
   820  		&m.Move{From: "labels", To: "workloadLabels"},
   821  		&m.Move{From: "annotations", To: "workloadAnnotations"},
   822  		&m.Move{From: "metadata/labels", To: "labels", NoDeleteFromField: true},
   823  		&m.Move{From: "metadata/annotations", To: "annotations", NoDeleteFromField: true},
   824  		&m.Drop{Field: "metadata"},
   825  		mapper.ContainerPorts{},
   826  		mapper.WorkloadAnnotations{},
   827  		&m.AnnotationField{Field: "publicEndpoints", List: true},
   828  		&m.AnnotationField{Field: "workloadMetrics", List: true},
   829  	}
   830  }
   831  
   832  func pipelineTypes(schema *types.Schemas) *types.Schemas {
   833  	baseProviderCustomizeFunc := func(schema *types.Schema) {
   834  		schema.BaseType = "sourceCodeProvider"
   835  		schema.ResourceActions = map[string]types.Action{
   836  			"login": {
   837  				Input:  "authUserInput",
   838  				Output: "sourceCodeCredential",
   839  			},
   840  		}
   841  		schema.CollectionMethods = []string{}
   842  		schema.ResourceMethods = []string{http.MethodGet}
   843  	}
   844  	return schema.
   845  		AddMapperForType(&Version, v3.SourceCodeProviderConfig{}).
   846  		AddMapperForType(&Version, v3.Pipeline{},
   847  			&m.Embed{Field: "status"},
   848  			m.DisplayName{}).
   849  		AddMapperForType(&Version, v3.PipelineExecution{},
   850  			&m.Embed{Field: "status"}).
   851  		AddMapperForType(&Version, v3.SourceCodeCredential{},
   852  			&m.Embed{Field: "status"}).
   853  		AddMapperForType(&Version, v3.SourceCodeRepository{}).
   854  		MustImport(&Version, v3.AuthAppInput{}).
   855  		MustImport(&Version, v3.AuthUserInput{}).
   856  		MustImport(&Version, v3.RunPipelineInput{}).
   857  		MustImport(&Version, v3.PushPipelineConfigInput{}).
   858  		MustImport(&Version, v3.GithubApplyInput{}).
   859  		MustImport(&Version, v3.GitlabApplyInput{}).
   860  		MustImport(&Version, v3.BitbucketCloudApplyInput{}).
   861  		MustImport(&Version, v3.BitbucketServerApplyInput{}).
   862  		MustImport(&Version, v3.BitbucketServerRequestLoginInput{}).
   863  		MustImport(&Version, v3.BitbucketServerRequestLoginOutput{}).
   864  		MustImportAndCustomize(&Version, v3.SourceCodeProvider{}, func(schema *types.Schema) {
   865  			schema.CollectionMethods = []string{http.MethodGet}
   866  		}).
   867  		MustImportAndCustomize(&Version, v3.GithubProvider{}, baseProviderCustomizeFunc).
   868  		MustImportAndCustomize(&Version, v3.GitlabProvider{}, baseProviderCustomizeFunc).
   869  		MustImportAndCustomize(&Version, v3.BitbucketCloudProvider{}, baseProviderCustomizeFunc).
   870  		MustImportAndCustomize(&Version, v3.BitbucketServerProvider{}, func(schema *types.Schema) {
   871  			schema.BaseType = "sourceCodeProvider"
   872  			schema.ResourceActions = map[string]types.Action{
   873  				"requestLogin": {
   874  					Output: "bitbucketServerRequestLoginOutput",
   875  				},
   876  				"login": {
   877  					Input:  "authUserInput",
   878  					Output: "sourceCodeCredential",
   879  				},
   880  			}
   881  			schema.CollectionMethods = []string{}
   882  			schema.ResourceMethods = []string{http.MethodGet}
   883  		}).
   884  		//Github Integration Config
   885  		MustImportAndCustomize(&Version, v3.SourceCodeProviderConfig{}, func(schema *types.Schema) {
   886  			schema.CollectionMethods = []string{http.MethodGet}
   887  		}).
   888  		MustImportAndCustomize(&Version, v3.GithubPipelineConfig{}, func(schema *types.Schema) {
   889  			schema.BaseType = "sourceCodeProviderConfig"
   890  			schema.ResourceActions = map[string]types.Action{
   891  				"disable": {},
   892  				"testAndApply": {
   893  					Input: "githubApplyInput",
   894  				},
   895  			}
   896  			schema.CollectionMethods = []string{}
   897  			schema.ResourceMethods = []string{http.MethodGet, http.MethodPut}
   898  		}).
   899  		MustImportAndCustomize(&Version, v3.GitlabPipelineConfig{}, func(schema *types.Schema) {
   900  			schema.BaseType = "sourceCodeProviderConfig"
   901  			schema.ResourceActions = map[string]types.Action{
   902  				"disable": {},
   903  				"testAndApply": {
   904  					Input: "gitlabApplyInput",
   905  				},
   906  			}
   907  			schema.CollectionMethods = []string{}
   908  			schema.ResourceMethods = []string{http.MethodGet, http.MethodPut}
   909  		}).
   910  		MustImportAndCustomize(&Version, v3.BitbucketCloudPipelineConfig{}, func(schema *types.Schema) {
   911  			schema.BaseType = "sourceCodeProviderConfig"
   912  			schema.ResourceActions = map[string]types.Action{
   913  				"disable": {},
   914  				"testAndApply": {
   915  					Input: "bitbucketCloudApplyInput",
   916  				},
   917  			}
   918  			schema.CollectionMethods = []string{}
   919  			schema.ResourceMethods = []string{http.MethodGet, http.MethodPut}
   920  		}).MustImportAndCustomize(&Version, v3.BitbucketServerPipelineConfig{}, func(schema *types.Schema) {
   921  		schema.BaseType = "sourceCodeProviderConfig"
   922  		schema.ResourceActions = map[string]types.Action{
   923  			"disable":      {},
   924  			"generateKeys": {},
   925  			"requestLogin": {
   926  				Input:  "bitbucketServerRequestLoginInput",
   927  				Output: "bitbucketServerRequestLoginOutput",
   928  			},
   929  			"testAndApply": {
   930  				Input: "bitbucketServerApplyInput",
   931  			},
   932  		}
   933  		schema.CollectionMethods = []string{}
   934  		schema.ResourceMethods = []string{http.MethodGet, http.MethodPut}
   935  	}).
   936  		MustImportAndCustomize(&Version, v3.Pipeline{}, func(schema *types.Schema) {
   937  			schema.ResourceActions = map[string]types.Action{
   938  				"activate":   {},
   939  				"deactivate": {},
   940  				"run": {
   941  					Input: "runPipelineInput",
   942  				},
   943  				"pushconfig": {
   944  					Input: "pushPipelineConfigInput",
   945  				},
   946  			}
   947  		}).
   948  		MustImportAndCustomize(&Version, v3.PipelineExecution{}, func(schema *types.Schema) {
   949  			schema.ResourceActions = map[string]types.Action{
   950  				"stop":  {},
   951  				"rerun": {},
   952  			}
   953  		}).
   954  		MustImportAndCustomize(&Version, v3.PipelineSetting{}, func(schema *types.Schema) {
   955  			schema.MustCustomizeField("name", func(f types.Field) types.Field {
   956  				f.Required = true
   957  				return f
   958  			})
   959  		}).
   960  		MustImportAndCustomize(&Version, v3.SourceCodeCredential{}, func(schema *types.Schema) {
   961  			delete(schema.ResourceFields, "namespaceId")
   962  			schema.ResourceMethods = []string{http.MethodGet, http.MethodDelete}
   963  			schema.ResourceActions = map[string]types.Action{
   964  				"refreshrepos": {},
   965  				"logout":       {},
   966  			}
   967  		}).
   968  		MustImportAndCustomize(&Version, v3.SourceCodeRepository{}, func(schema *types.Schema) {
   969  			delete(schema.ResourceFields, "namespaceId")
   970  			schema.ResourceMethods = []string{http.MethodGet, http.MethodDelete}
   971  		})
   972  
   973  }
   974  
   975  func monitoringTypes(schemas *types.Schemas) *types.Schemas {
   976  	return schemas.
   977  		AddMapperForType(&Version, monitoringv1.Prometheus{},
   978  			&m.Drop{Field: "status"},
   979  			&m.AnnotationField{Field: "description"},
   980  		).
   981  		AddMapperForType(&Version, monitoringv1.PrometheusSpec{},
   982  			&m.Drop{Field: "thanos"},
   983  			&m.Drop{Field: "apiserverConfig"},
   984  			&m.Drop{Field: "serviceMonitorNamespaceSelector"},
   985  			&m.Drop{Field: "ruleNamespaceSelector"},
   986  			&m.Drop{Field: "paused"},
   987  			&m.Enum{
   988  				Field: "logLevel",
   989  				Options: []string{
   990  					"all",
   991  					"debug",
   992  					"info",
   993  					"warn",
   994  					"error",
   995  					"none",
   996  				},
   997  			},
   998  		).
   999  		MustImportAndCustomize(&Version, monitoringv1.Prometheus{}, func(schema *types.Schema) {
  1000  			schema.MustCustomizeField("name", func(field types.Field) types.Field {
  1001  				field.Type = "dnsLabelRestricted"
  1002  				field.Nullable = false
  1003  				field.Required = true
  1004  				return field
  1005  			})
  1006  		}, projectOverride{}, struct {
  1007  			Description string `json:"description"`
  1008  		}{}).
  1009  		AddMapperForType(&Version, monitoringv1.RelabelConfig{},
  1010  			&m.Enum{
  1011  				Field: "action",
  1012  				Options: []string{
  1013  					"replace",
  1014  					"keep",
  1015  					"drop",
  1016  					"hashmod",
  1017  					"labelmap",
  1018  					"labeldrop",
  1019  					"labelkeep",
  1020  				},
  1021  			},
  1022  		).
  1023  		AddMapperForType(&Version, monitoringv1.Endpoint{},
  1024  			&m.Drop{Field: "port"},
  1025  			&m.Drop{Field: "tlsConfig"},
  1026  			&m.Drop{Field: "bearerTokenFile"},
  1027  			&m.Drop{Field: "honorLabels"},
  1028  			&m.Drop{Field: "basicAuth"},
  1029  			&m.Drop{Field: "metricRelabelings"},
  1030  			&m.Drop{Field: "proxyUrl"},
  1031  		).
  1032  		AddMapperForType(&Version, monitoringv1.ServiceMonitorSpec{},
  1033  			&m.Embed{Field: "namespaceSelector"},
  1034  			&m.Drop{Field: "any"},
  1035  			&m.Move{From: "matchNames", To: "namespaceSelector"},
  1036  		).
  1037  		AddMapperForType(&Version, monitoringv1.ServiceMonitor{},
  1038  			&m.AnnotationField{Field: "displayName"},
  1039  			&m.DisplayName{},
  1040  			&m.AnnotationField{Field: "targetService"},
  1041  			&m.AnnotationField{Field: "targetWorkload"},
  1042  		).
  1043  		MustImport(&Version, monitoringv1.ServiceMonitor{}, projectOverride{}, struct {
  1044  			DisplayName    string `json:"displayName,omitempty"`
  1045  			TargetService  string `json:"targetService,omitempty"`
  1046  			TargetWorkload string `json:"targetWorkload,omitempty"`
  1047  		}{}).
  1048  		MustImport(&Version, monitoringv1.PrometheusRule{}, projectOverride{}).
  1049  		AddMapperForType(&Version, monitoringv1.Alertmanager{},
  1050  			&m.Drop{Field: "status"},
  1051  		).
  1052  		MustImport(&Version, monitoringv1.Alertmanager{}, projectOverride{})
  1053  }
  1054  
  1055  func autoscalingTypes(schemas *types.Schemas) *types.Schemas {
  1056  	return schemas.
  1057  		AddMapperForType(&Version, autoscaling.HorizontalPodAutoscaler{},
  1058  			&m.ChangeType{Field: "scaleTargetRef", Type: "reference[workload]"},
  1059  			&m.Move{From: "scaleTargetRef", To: "workloadId"},
  1060  			mapper.CrossVersionObjectToWorkload{Field: "workloadId"},
  1061  			&m.Required{Fields: []string{"workloadId", "maxReplicas"}},
  1062  			&m.AnnotationField{Field: "displayName"},
  1063  			&m.DisplayName{},
  1064  			&m.AnnotationField{Field: "description"},
  1065  			&m.Embed{Field: "status"},
  1066  			mapper.NewMergeListByIndexMapper("currentMetrics", "metrics", "type"),
  1067  		).
  1068  		AddMapperForType(&Version, autoscaling.MetricTarget{},
  1069  			&m.Enum{Field: "type", Options: []string{"Utilization", "Value", "AverageValue"}},
  1070  			&m.Move{To: "utilization", From: "averageUtilization"},
  1071  		).
  1072  		AddMapperForType(&Version, autoscaling.MetricValueStatus{},
  1073  			&m.Move{To: "utilization", From: "averageUtilization"},
  1074  		).
  1075  		AddMapperForType(&Version, autoscaling.MetricSpec{},
  1076  			&m.Condition{Field: "type", Value: "Object", Mapper: types.Mappers{
  1077  				&m.Move{To: "target", From: "object/target", DestDefined: true, NoDeleteFromField: true},
  1078  				&m.Move{To: "metric", From: "object/metric", DestDefined: true, NoDeleteFromField: true},
  1079  			}},
  1080  			&m.Condition{Field: "type", Value: "Pods", Mapper: types.Mappers{
  1081  				&m.Move{To: "target", From: "pods/target", DestDefined: true, NoDeleteFromField: true},
  1082  				&m.Move{To: "metric", From: "pods/metric", DestDefined: true, NoDeleteFromField: true},
  1083  			}},
  1084  			&m.Condition{Field: "type", Value: "Resource", Mapper: types.Mappers{
  1085  				&m.Move{To: "metric/name", From: "resource/name", DestDefined: true, NoDeleteFromField: true},
  1086  				&m.Move{To: "target", From: "resource/target", DestDefined: true, NoDeleteFromField: true},
  1087  			}},
  1088  			&m.Condition{Field: "type", Value: "External", Mapper: types.Mappers{
  1089  				&m.Move{To: "target", From: "external/target", DestDefined: true, NoDeleteFromField: true},
  1090  				&m.Move{To: "metric", From: "external/metric", DestDefined: true, NoDeleteFromField: true},
  1091  			}},
  1092  			&m.Embed{Field: "object", Ignore: []string{"target", "metric"}},
  1093  			&m.Embed{Field: "pods", Ignore: []string{"target", "metric"}},
  1094  			&m.Embed{Field: "external", Ignore: []string{"target", "metric"}},
  1095  			&m.Embed{Field: "resource", Ignore: []string{"target", "name"}},
  1096  			&m.Embed{Field: "metric"},
  1097  			&m.Enum{Field: "type", Options: []string{"Object", "Pods", "Resource", "External"}},
  1098  		).
  1099  		MustImportAndCustomize(&Version, autoscaling.MetricSpec{}, func(s *types.Schema) {
  1100  			s.CodeName = "Metric"
  1101  			s.PluralName = "metrics"
  1102  			s.ID = "metric"
  1103  			s.CodeNamePlural = "Metrics"
  1104  		}, struct {
  1105  			Target  autoscaling.MetricTarget      `json:"target"`
  1106  			Metric  autoscaling.MetricIdentifier  `json:"metric"`
  1107  			Current autoscaling.MetricValueStatus `json:"current" norman:"nocreate,noupdate"`
  1108  		}{}).
  1109  		AddMapperForType(&Version, autoscaling.MetricStatus{},
  1110  			&m.Condition{Field: "type", Value: "Object", Mapper: &m.Move{To: "current", From: "object/current", DestDefined: true, NoDeleteFromField: true}},
  1111  			&m.Condition{Field: "type", Value: "Pods", Mapper: &m.Move{To: "current", From: "pods/current", DestDefined: true, NoDeleteFromField: true}},
  1112  			&m.Condition{Field: "type", Value: "Resource", Mapper: &m.Move{To: "current", From: "resource/current"}},
  1113  			&m.Condition{Field: "type", Value: "External", Mapper: &m.Move{To: "current", From: "external/current", DestDefined: true, NoDeleteFromField: true}},
  1114  		).
  1115  		MustImport(&Version, autoscaling.HorizontalPodAutoscaler{}, projectOverride{}, struct {
  1116  			DisplayName string `json:"displayName,omitempty"`
  1117  			Description string `json:"description,omitempty"`
  1118  		}{})
  1119  }
  1120  
  1121  func istioTypes(schemas *types.Schemas) *types.Schemas {
  1122  	return schemas.
  1123  		MustImport(&Version, istiov1alpha3.HTTPMatchRequest{}, struct {
  1124  			Port *uint32 `json:"port,omitempty"`
  1125  		}{}).
  1126  		MustImport(&Version, istiov1alpha3.HTTPRoute{}, struct {
  1127  			WebsocketUpgrade *bool `json:"websocketUpgrade,omitempty"`
  1128  		}{}).
  1129  		MustImport(&Version, istiov1alpha3.VirtualService{}, projectOverride{}, struct {
  1130  			Status interface{}
  1131  		}{}).
  1132  		MustImport(&Version, istiov1alpha3.ConsistentHashLB{}, struct {
  1133  			UseSourceIP *bool `json:"useSourceIp,omitempty"`
  1134  		}{}).
  1135  		MustImport(&Version, istiov1alpha3.DestinationRule{}, projectOverride{}, struct {
  1136  			Status interface{}
  1137  		}{}).
  1138  		MustImport(&Version, istiov1alpha3.Gateway{}, projectOverride{}, struct {
  1139  			Status interface{}
  1140  		}{})
  1141  }