apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  annotations:
    addons.oam.dev/description: istio Controller is a Kubernetes Controller for manage
      traffic.
  name: istio
  namespace: vela-system
spec:
  components:
  - name: ns-istio-system
    properties:
      apiVersion: v1
      kind: Namespace
      metadata:
        name: istio-system
    type: raw
  - name: istio
    properties:
      chart: istio
      repoType: helm
      url: https://charts.kubevela.net/addons
      version: 1.11.1
    type: helm
  - name: canary-rollout
    properties:
      apiVersion: core.oam.dev/v1beta1
      kind: WorkflowStepDefinition
      metadata:
        name: canary-rollout
        namespace: vela-system
      spec:
        schematic:
          cue:
            template: |-
              import ("vela/op")

              parameter: {
                      batchPartition: int
                      traffic: weightedTargets: [...{
                              revision: string
                              weight:   int
                      }]
              }

              comps__: op.#Load
              compNames__: [ for name, c in comps__.value {name}]
              comp__: compNames__[0]

              apply: op.#ApplyComponent & {
                      value: comps__.value[comp__]
                      patch: {
                              traits: "rollout": {
                                     spec: rolloutPlan: batchPartition: parameter.batchPartition
                              }

                              traits: "virtualService": {
                                      spec:
                                         // +patchStrategy=retainKeys
                                         http: [
                                              {
                                                      route: [
                                                              for i, t in parameter.traffic.weightedTargets {
                                                                      destination: {
                                                                              host:   comp__
                                                                              subset: t.revision
                                                                      }
                                                                      weight: t.weight
                                                              }]
                                              },
                                      ]
                              }

                              traits: "destinationRule": {
                                       // +patchStrategy=retainKeys
                                       spec: {
                                         host: comp__
                                         subsets: [
                                              for i, t in parameter.traffic.weightedTargets {
                                                      name: t.revision
                                                      labels: {"app.oam.dev/revision": t.revision}
                                              },
                                      ]}
                              }
                      }
              }

              applyRemaining: op.#ApplyRemaining & {
                  exceptions: [comp__]
              }
    type: raw
  - name: istio-gateway
    properties:
      apiVersion: core.oam.dev/v1beta1
      kind: TraitDefinition
      metadata:
        annotations:
          definition.oam.dev/description: use istio to manage in-cluster traffic
        name: istio-gateway
        namespace: vela-system
      spec:
        appliesToWorkloads:
        - deployments.apps
        podDisruptive: true
        schematic:
          cue:
            template: "\noutputs: gateway: {\n    apiVersion: \"networking.istio.io/v1alpha3\"\n
              \   kind: \"Gateway\"\n    metadata: {\n        name:      context.name\n
              \       namespace: context.namespace\n    }\n    spec: {\n      selector:
              {\n        istio: parameter.gateway\n      }\n      servers: [{\n         hosts:
              parameter.hosts\n         port: {\n              name: \"http\"\n              number:
              80\n              protocol: \"HTTP\"\n         }\n      }]\n    }\n}\n\noutputs:
              virtualService: {\n    apiVersion: \"networking.istio.io/v1alpha3\"\n
              \   kind: \"VirtualService\"\n    metadata: {\n         name:      context.name\n
              \        namespace: context.namespace\n    }\n    spec: {\n       gateways:
              [context.name]\n       hosts: parameter.hosts\n       http:[{\n       match:
              [ for i, u in parameter.match { uri: u} ]\n       route: [{destination:
              {\n           host: context.name\n           port: number: parameter.port\n
              \      }}]\n       }]\n    }\n}\n\nparameter: {\n    hosts: [string]\n
              \   gateway: *\"ingressgateway\"|string\n    match: [...#uri]\n    port:
              int\n}\n\n#uri: {\n   exact?: string\n   prefix?: string\n} \n"
    type: raw
  - name: canary-rollback
    properties:
      apiVersion: core.oam.dev/v1beta1
      kind: WorkflowStepDefinition
      metadata:
        name: canary-rollback
        namespace: vela-system
      spec:
        schematic:
          cue:
            template: |-
              import ("vela/op")

              parameter: {...}

              comps: op.#Load
              compNames: [ for name, c in comps.value {name}]
              firstcomp: compNames[0]

              rolloutObj: op.#Read & {
                value: {
                  apiVersion: "standard.oam.dev/v1alpha1"
                  kind:       "Rollout"
                  metadata: {
                    name:      firstcomp
                    namespace: context.namespace
                  }
                }
              }

              _sourceRevision: rolloutObj.value.status.LastSourceRevision

              apply: op.#ApplyComponent & {
                value: comps.value[firstcomp]
                patch: {
                  traits: "rollout": {
                    spec: {
                      targetRevisionName: _sourceRevision
                    }
                  }

                  traits: "virtualService": {
                    spec:
                      // +patchStrategy=retainKeys
                      http: [
                        {
                          route: [{
                            destination: {
                              host:   firstcomp
                              subset: _sourceRevision
                            }
                            weight: 100
                          }]
                        },
                      ]
                  }

                  traits: "destinationRule": {
                    // +patchStrategy=retainKeys
                    spec: {
                      host: firstcomp
                      subsets: [
                        {
                          name: _sourceRevision
                          labels: {"app.oam.dev/revision": _sourceRevision}
                        },
                      ]
                    }
                  }
                }
              }

              applyRemaining: op.#ApplyRemaining & {
                  exceptions: [firstcomp]
              }
    type: raw
  - name: canary-traffic
    properties:
      apiVersion: core.oam.dev/v1beta1
      kind: TraitDefinition
      metadata:
        annotations:
          definition.oam.dev/description: use istio to manage traffic
        name: canary-traffic
        namespace: vela-system
      spec:
        appliesToWorkloads:
        - deployments.apps
        podDisruptive: true
        schematic:
          cue:
            template: "outputs: service: {\n\t\tapiVersion: \"v1\"\n\t\tkind:       \"Service\"\n\t\tmetadata:
              name: context.name\n\t\tspec: {\n\t\t\tselector: \"app.oam.dev/component\":
              context.name\n\t\t\tports: [\n\t\t\t\tfor p in parameter.port {\n\t\t\t\t\tport:
              \      p\n\t\t\t\t\ttargetPort: p\n\t\t\t\t},\n\t\t\t]\n\t\t\ttype:
              \"ClusterIP\"\n\t\t}\n}\n\noutputs: virtualService: {\n    apiVersion:
              \"networking.istio.io/v1alpha3\"\n    kind: \"VirtualService\"\n    metadata:
              {\n        name:      context.name\n        namespace: context.namespace\n
              \   }\n    spec: {\n       hosts: [context.name]\n       http: [{route:
              [\n       {destination: {\n          host: context.name\n          port:
              {number: parameter.port[0]}\n       }}]}]\n    }\n}\n\noutputs: destinationRule:
              {\n       apiVersion: \"networking.istio.io/v1alpha3\"\n       kind:
              \"DestinationRule\"\n       metadata: {\n           name:      context.name\n
              \          namespace: context.namespace\n       }\n       spec: {\n
              \         host: context.name\n          subsets: [{\n             name:
              context.revision\n             labels: {\"app.oam.dev/revision\": context.revision}\n
              \         }]\n       }\n}\n\nparameter: {\n   port: [int]\n} \n"
    type: raw
  workflow:
    steps:
    - name: checking-depends-on
      properties:
        name: fluxcd
        namespace: vela-system
      type: depends-on-app
    - name: apply-ns
      properties:
        component: ns-istio-system
      type: apply-component
    - name: apply-resources
      type: apply-remaining
status:
  rollout:
    batchRollingState: ""
    currentBatch: 0
    lastTargetAppRevision: ""
    rollingState: ""
    upgradedReadyReplicas: 0
    upgradedReplicas: 0
