ploigos / ploigos-step-runner

Ploigos Step Runner (PSR) implemented as a Python library.
GNU General Public License v3.0
20 stars 66 forks source link

Service mesh support for UAT step #299

Open cmasonrh opened 1 year ago

cmasonrh commented 1 year ago

Realized I opened this originally in the wrong repo

We are currently using the UAT step to perform automated testing via a project deployed via ArgoCD. We have recently switched from using route objects to using service mesh (specifically ingress-gateway) for exposing our endpoints. However the UAT step only parses though ingress and route objects returned by deployment. Since these are not being deployed by our application the UAT step is failing because it gets 0 host urls. We would like to see if there is any current planned support for service mesh or if a PR for service mesh support being added to UAT would be a welcome addition.

itewk commented 1 year ago

heyo @cmasonrh we dont have anyone who can implement that RFE right now, but it shouldn't be too dificult to do if you were willing to put in a PR for be happy to review and get it merged.

the bit of code you would need to enhance is here: https://github.com/ploigos/ploigos-step-runner/blob/d0a7f54c7895c252f40b9625decb9b69de0147c9/src/ploigos_step_runner/step_implementers/shared/argocd_generic.py#L211

itewk commented 1 year ago

@cmasonrh if you can get me some example CRs for the ingress-gateway ill see if i can prototype you out a patch that will work if you can do runtime tests since i dont have a runtime test environment set up right now. specifically need like yaml exports of the ingress-gateway CRs at runtime. feel free to anonymized what should be anonymized.

cmasonrh commented 1 year ago

I'll try and pull together some examples.

cmasonrh commented 1 year ago

That's for the help @itewk here are some lengthy details. @bcarr-redhat is also working on this.

Here are some example gateway configs. They contain the files we use as well as the route that is automatically created.

In the case where gateway - spec: selector: servers: hosts: contains a list with ‘*’ as an entry that uses the default gateway. In our case that is istio-ingressgateway-istio-system, then the rest of the cluster's hostname is added ie (apps.). The path comes from virtualservice spec: http: match: uri: exact:

apiVersion: maistra.io/v1
kind: ServiceMeshMember
metadata:
  labels:
    app.kubernetes.io/instance: ploigos-ref-ref-quarkus-mvn-fruita-main-dev
  name: default
  namespace: app-fruita-dev
spec:
  controlPlaneRef:
    name: basic
    namespace: istio-system
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: fruita
  namespace: app-fruita-dev
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - '*'
      port:
        name: http
        number: 80
        protocol: HTTP
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  labels:
    app.kubernetes.io/instance: ploigos-ref-ref-quarkus-mvn-fruita-main-dev
  name: fruita
  namespace: app-fruita-dev
spec:
  gateways:
    - app-fruita-dev/fruita
  hosts:
    - '*'
  http:
    - match:
        - uri:
            exact: /app-fruita-dev/fruits
      rewrite:
        uri: /fruits
      route:
        - destination:
            host: fruita.app-fruita-dev.svc.cluster.local
            port:
              number: 44

Route created by Service Mesh

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  annotations:
    maistra.io/original-host: '*'
    openshift.io/host.generated: 'true'
  labels:
    app.kubernetes.io/instance: ploigos-ref-ref-quarkus-mvn-fruita-main-dev
    maistra.io/gateway-name: fruita
    maistra.io/gateway-namespace: app-fruita-dev
    maistra.io/gateway-resourceVersion: '779553387'
    maistra.io/generated-by: ior
    app.router: external
  name: app-fruita-dev-fruita-525eca1d5089dbdc
  namespace: istio-system
spec:
  host: >-
    app-fruita-dev-fruita-525eca1d5089dbdc-istio-system.apps.cluster_hostname
  port:
    targetPort: http2
  to:
    kind: Service
    name: istio-ingressgateway
    weight: 100
  wildcardPolicy: None

URL = https://istio-ingressgateway-istio-system.apps.cluster_host/app-fruitb-dev/fruits

In the case where spec: selector: servers: hosts: contains an actual host that can be used as is.

apiVersion: maistra.io/v1
kind: ServiceMeshMember
metadata:
  labels:
    app.kubernetes.io/instance: ploigos-ref-ref-quarkus-mvn-fruita-main-impl
  name: default
  namespace: app-fruita-impl
spec:
  controlPlaneRef:
    name: basic
    namespace: istio-system
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  labels:
    app.kubernetes.io/instance: ploigos-ref-ref-quarkus-mvn-fruita-main-impl
    app.router: external
  name: fruita
  namespace: app-fruita-impl
spec:
  selector:
    app: reference-quarkus-mvn-deploy-fruita-app-fruita-impl
  servers:
    - hosts:
        - fruita-impl.externalhost.com
      port:
        name: http
        number: 80
        protocol: HTTP
      tls:
        httpsRedirect: true
    - hosts:
        - fruita-impl.externalhost.com
      port:
        name: https
        number: 443
        protocol: HTTPS
      tls:
        credentialName: reference-quarkus-mvn-deploy-fruita-tls-cert
        mode: SIMPLE
``
``
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  labels:
    app.kubernetes.io/instance: ploigos-ref-ref-quarkus-mvn-fruita-main-impl
  name: fruita
  namespace: app-fruita-impl
spec:
  gateways:
    - app-fruita-impl/fruita
  hosts:
    - fruita-impl.externalhost.com
  http:
    - match:
        - uri:
            exact: /app-fruita-impl/fruits
      rewrite:
        uri: /fruits
      route:
        - destination:
            host: fruita.app-fruita-impl.svc.cluster.local
            port:
              number: 44

Route created by Service Mesh

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  annotations:
    maistra.io/original-host: fruita-impl.externalhost.com
  labels:
    app.kubernetes.io/instance: ploigos-ref-ref-quarkus-mvn-fruita-main-impl
    maistra.io/gateway-name: fruita
    maistra.io/gateway-namespace: app-fruita-impl
    maistra.io/gateway-resourceVersion: '729534922'
    maistra.io/generated-by: ior
    app.router: external
  name: app-fruita-impl-fruita-285003a89a43a6fe
  namespace: app-fruita-impl
spec:
  host: fruita-impl.externalhost.com
  port:
    targetPort: https
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: passthrough
  to:
    kind: Service
    name: fruita
    weight: 100
  wildcardPolicy: None

URL = https://fruita-impl.externalhost.com/

itewk commented 1 year ago

@cmasonrh so which URL do you want passed onto the UAT step? https://fruita-impl.externalhost.com/ which is coming from the generated route?

cmasonrh commented 1 year ago

@itewk So in the case where one is supplied via the gateway then yes the route is fine. However if like in the gateway example where the default '*' is used it needs to be calculated from a couple of different places.

itewk commented 1 year ago

hrmmmm. im not putting all the peices togeather. can we grab some time to chat next week, maybe do some show and tell?

cmasonrh commented 1 year ago

Yeah, that would work. Might want to include @bcarr-redhat as he has more service mesh experience than I. Should we schedule it or do you want to do that?

itewk commented 1 year ago

@cmasonrh @bcarr-redhat invite sent. we will post updates here after convo.

cmasonrh commented 1 year ago

To summarize the logic discussed in the meeting.

For wildcard (default) gateways (gateway spec:hosts = *) the URL is calculated as follows. istio-\<Gateway spec:selector:istio>-\<ServiceMeshMember spec:controlPlaneRef:namespace>\<VirtualService spec:http:match:uri:exact>

istio is static, followed by the istio selector from gateway resource, next is the namespace from the service mesh member controlplane namespace, and then the path from the virtual service url match.

For non wildcard gateways where hosts is not * just use the host from the gateway spec:hosts.