OpenShift-Build-Pipelines:
Build ► Test ► Run!
Tobias Schneck,
Testautomatisierung @ ConSol Software GmbH
+
Agenda
• OpenShift CI/CD Pipeline Konzept
• Build up a Build Pipelines!
• Stage I: CI-Build bis zum Artefakt
• Stage II: Automated Testing
− Citrus Integration Testing
− Sakuli E2E Testing
• Stage III: Artefakt Deployment
• Review
• Alternativen
• Links
OpenShift CI/CD Pipeline Konzept
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 4
Prozess Development ► QA Stage
OPS
Code
Build &
Unit-Test
Deploy in Dev
Container
Image
Container
Registry
POD
AUTOMATIC
MANUEL ODER AUTOMATIC
POD
Deploy in QA
► Test
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 5
Prozess QA ► Production Stage
OPS
Deploy in
Production
►Smoke-Test
Container
Image from QA Stage
MANUEL
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 6
OpenShift Core Components
CI / CD
Build Pipeline?
Jenkins Integration
+ Jenkins Template
+ OpenShift Jenkins Client Plugin
+ OpenShift Jenkins Sync Plugin
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 7
OpenShift Regular Builds (tradional)
Execution Node
OpenShift
Builder Pod
OpenShift
Master
Scheduler
OpenShift
Internal
Registry
Image Stream
(Project/Global)
Source-2-
Image Build
Docker
native Build
build.yml Dockerfile
Image Artifcat
Builder Image Base Image
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 8
OpenShift CI Pipeline Build
Execution Node
OpenShift
Builder Pod
OpenShift
Master
Scheduler
OpenShift
Internal
Registry
Image Stream
(Project/Global)
Image Artifcat
Jenkins Image
Maven Image
…
Jenkinsfile
Jenkins
Pipeline Build
OpenShift
Regular Build
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 9
OpenShift CI Pipeline Build
Execution Node
OpenShift
Builder Pod
OpenShift
Master
Scheduler
OpenShift
Internal
Registry
Image Stream
(Project/Global)
Image Artifcat
Jenkins Image
Maven Image
…
Jenkinsfile
Jenkins
Pipeline Build
OpenShift
Regular Build
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 10
● Uses OpenShift CLI: oc
○ Automatically authorized
○ Use complete CLI possibilities
○ Huge flexibility
● Uses OpenShift Jenkins Client Plugin
○ Based on Jenkins kubernetes-plugin
○ Groovy wrapper for OpenShift API
○ Enables dynamic slave images
- built-in images: base, maven, nodejs
- custom images
OpenShift Build & Deploy with Jenkinsfile
Jenkins Image
Jenkinsfile
Maven Image
Node Image
…
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 11
OpenShift Custom Jenkins Slave
Jenkinsfile
podTemplate(label: "citrus",
cloud: "openshift",
inheritFrom: "maven",
containers: [
containerTemplate(name: "jnlp",
image: "toschneck/citrus-jenkins-slave",
)
])
{
node('citrus') {
sh "echo execute oc citrus build"
checkout scm
sh "mvn install"
junit 'citrus-tests/target/citrus-reports/**/*.xml'
archiveArtifacts "citrus-tests/target/citrus-*/**/*"
}
}
Used by
citrusframework/citrus-docker-images PR #3
FROM consol/citrus:2.7.5
### sourced are copied from:
# https://github.com/openshift/jenkins/tree/master/slave-base
# https://github.com/openshift/jenkins/tree/master/slave-maven
# Copy the jenkins-slave entrypoint
ADD contrib/bin/* /usr/local/bin/
# Run the Jenkins JNLP client
ENTRYPOINT ["/usr/local/bin/run-jnlp-client"]
Build up a Build Pipeline!
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 13
Bakery App
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 14
Bakery App
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 15
Transformation to OpenShift
Ziele:
• Sourcecode der Apps nicht verändern
• Testcode nicht verändern
• Vollautomatisiert bis in die Produktion
• All-in-OpenShift (CI, Build, Test, Deployment)
• Jenkins v1 -> v2
Stage I: CI-Build bis zum Artefakt
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 17
CI Build ► Docker Image
build.pipeline.yml Jenkinsfile.dev
Maven Image
Dockerfiles
OpenShift
Regular Build
Docker Image
Artifact
DEMO
toschneck/openshift-example-bakery-ci-pipeline
Stage II: Automated Testing
Citrus Integration Testing
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 21
Mission: Integrationstest
Automatisierte Schnittstellentests
System
Under Test
Verträge
Stammdaten
Dienstleister
Shipping
JM
S
XM
L
FTP
CSV
Webclient
Kunde
Agent /
Techniker
Mobile, PDA
Http
REST
Http
SOAP
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 22
Mission: Integrationstest
System
Under Test
Stammdaten
Dienstleister
JM
S
XM
L
FTP
CSV
Kunde
Agent /
Techniker
Http
REST
Http
SOAP
Automatisierte Schnittstellentests
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 23
Citrus Features
• Ready to use components
− Client & Server
• Message transports
− Http REST, SOAP, JMS, FTP, TCP/IP, Mail, RMI, SSH, ...
• Data formats
− XML, Json, PlainText, CSV, XSD, WSDL
• Test DSL
− XML & Java
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 24
Usage: Middleware Integration / ESB
• Bittner&Krull KSS
> 300 Tests
• M-net Atlas ESB
> 800 Tests
• Telefonica o2 NMF, COM
> 150 Tests, > 500 Tests
• Vodafone UC
> 250 Tests
• Media Saturn ESB
> 200 Tests
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 25
more Citrus
• Citrus Admin UI
• Easy Testsuite Management
• Reporting
• Citrus Simulator
• Complex Messaging Workflow Simulation
• Predefined Interface Packages: WBCI, WITA
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 26
QA -> Citrus API Integration Tests
Citrus Slave Image
build.pipeline.yml Jenkinsfile.qa
DEMO
toschneck/openshift-example-bakery-ci-pipeline
E2E Testing
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 29
Sakuli End-to-End Use Cases
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 30
Motivation
• Gründung February 2014 Open Source (Apache)
• Ziele:
− zwei Open Source Automation Tools „verheiraten“
− Verarbeitung der Ergebnisse an CI- u. Montioringsysteme
− Plattformunabhängigkeit (Linux/Windows/MacOS)
• Applikationstests mit der "Userbrille"
− Funktionalität
− Performance (Ladezeiten)
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 31
Referenzen
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 32
Component 1: Sahi / Selenium
Web testing tool (sahi.co.in, seleniumhq.org)
method based DOM access:
_assertContainsText ("Logged in as: Sakuli", _div("user_field"));
_click(_span("Loaded Run Tabels"));
_assertExists(_table("cross_table_fixed"));
_assertExists(_cell(“testing allowed", _rightOf(_span("Name")), _under(_cell("Action")));
<table>
<tbody>
<tr>
<td>Alice</td>
<td>Bob</td>
</tr>
</tbody>
</table>
Webserverlocalhost:9999
{js}
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 33
Component 2: Sikuli
Visual automation tool (sikuli.org)
image identification, mouse & keyboard interaction:
screen.find("sap_ok").click();
screen.find("sap_ok").right(40).click().type("2223");
var bubble = new Region().waitForImage("bubble.png", 20);
bubble.dragAndDropTo(bubble.left(35)).highlight();
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 34
Vergleich: Sahi/Selenium & Sikuli
Sikuli
universell, kompl. Bildschirm
ressourcenintensiv(er)
braucht "freie Sicht"
Sahi / Selenium
beschränkt auf web,
(kein Flash, Java applets...)
schnell
effizient zu schreiben
(Controller + Recorder)
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 35
Mehrwert
• Erlaubt den Einsatz beider Tools zugleich
• Step-by-step code (JavaScript, Java)
• Automatische Screenshots im Fehlerfall
• Cloud-ready Docker-Images für Kubernets/OpenShift
• Sakuli UI für Pflege, Ausführung und Reporting (beta)
• "Forwarder"-Module:
− Monitoring (Gearman, Icinga, CheckMK)
− CI (Jenkins...)
− Datenbanken (MySQL/MariaDB, ...)
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 36
Monitoring Integration
Service Check (OMD - Thruk)
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 37
Sakuli End-2-End Testing Container
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 38
QA -> tested Docker Image
Docker Image
Artifcat
Citrus Slave Image SakuliImage
build.pipeline.yml Jenkinsfile.qa
DEMO
toschneck/openshift-example-bakery-ci-pipeline
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 40
Review
• Jenkins wurde nicht desingend für Container/Pods
Plugins, Startup, Java Agents, lokales Filesystem
• Migration zu Jenkinsfiles
• Viele Wrapper-Scripte, um flexibel zu sein
• Verteiltes CI-Design erfordert ein Umdenken
• CI-Daten schwerer zugänglich
Logs, Screenshots, Artifakte
• Technologie-Mix
• Slave-Image intransparent -> do it your self
Base Image: github.com/openshift/jenkins/slave-base
• Verteilte Dokumentation
OpenShift, Kubernetes, Jenkins, Jenkins-Plugins, Docker, …
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 41
Review
• Skalierung übernimmt der Cluster
• "oc CLI client" anstatt Openshift-Jenkins-Plugin
► Pipeline modular test/entwickelbar
• Parametrisierte YAML Templates für OpenShift
• Infrastructur as Code
• Neue Stages sind einfach zu erstellen
• Deployment wird automatisch mitgetestet
• Secrets durch Cluster-Admins verwaltbar
• Builds Steuerbar von CLI und UI
• Erweiterbarkeit durch OpenSource
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 42
Alternative Ansätze
hasura/gitkube
⇨ Gitkube
• “git push” based Workflow on remote Git
• Simple: Kombination von bash Scripts
⇨ DroneCI / KubeCI
• Container first und einfache Konzept
• Nutzbar für gebaute Images
• Layered Build Concept für Pods (in Entwicklung)
⇨ Skaffold:
• Einfacher CI/CD Workflow
• 2 Stages: Local & Remote
⇨ JenkinsX
• Vordefinierter Workflow für CI/CD in Kubernetes
• kein neuer Jenkins -> Wrapper
• GitHub only
GoogleContainerTools/skaffold
kubeciiodrone/drone
jenkins-x/jx
OpenShift-Build-Pipelines: Build -> Test -> Run! Folie 43
Links
toschneck/openshift-example-bakery-ci-pipeline
citrusframework/citrus www.citrusframework.org
ConSol/sakuli www.sakuli.org
@toschneck
@citrus_test
@sakuli_e2e
Fragen?
Vielen Dank!
ConSol
Consulting & Solutions Software GmbH
Franziskanerstr. 38
D-81669 München
Tel.: +49-89-45841-100
info@consol.de
www.consol.de
Twitter: @consol_de

OpenShift-Build-Pipelines: Build ► Test ► Run!

  • 1.
    OpenShift-Build-Pipelines: Build ► Test► Run! Tobias Schneck, Testautomatisierung @ ConSol Software GmbH
  • 2.
    + Agenda • OpenShift CI/CDPipeline Konzept • Build up a Build Pipelines! • Stage I: CI-Build bis zum Artefakt • Stage II: Automated Testing − Citrus Integration Testing − Sakuli E2E Testing • Stage III: Artefakt Deployment • Review • Alternativen • Links
  • 3.
  • 4.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 4 Prozess Development ► QA Stage OPS Code Build & Unit-Test Deploy in Dev Container Image Container Registry POD AUTOMATIC MANUEL ODER AUTOMATIC POD Deploy in QA ► Test
  • 5.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 5 Prozess QA ► Production Stage OPS Deploy in Production ►Smoke-Test Container Image from QA Stage MANUEL
  • 6.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 6 OpenShift Core Components CI / CD Build Pipeline? Jenkins Integration + Jenkins Template + OpenShift Jenkins Client Plugin + OpenShift Jenkins Sync Plugin
  • 7.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 7 OpenShift Regular Builds (tradional) Execution Node OpenShift Builder Pod OpenShift Master Scheduler OpenShift Internal Registry Image Stream (Project/Global) Source-2- Image Build Docker native Build build.yml Dockerfile Image Artifcat Builder Image Base Image
  • 8.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 8 OpenShift CI Pipeline Build Execution Node OpenShift Builder Pod OpenShift Master Scheduler OpenShift Internal Registry Image Stream (Project/Global) Image Artifcat Jenkins Image Maven Image … Jenkinsfile Jenkins Pipeline Build OpenShift Regular Build
  • 9.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 9 OpenShift CI Pipeline Build Execution Node OpenShift Builder Pod OpenShift Master Scheduler OpenShift Internal Registry Image Stream (Project/Global) Image Artifcat Jenkins Image Maven Image … Jenkinsfile Jenkins Pipeline Build OpenShift Regular Build
  • 10.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 10 ● Uses OpenShift CLI: oc ○ Automatically authorized ○ Use complete CLI possibilities ○ Huge flexibility ● Uses OpenShift Jenkins Client Plugin ○ Based on Jenkins kubernetes-plugin ○ Groovy wrapper for OpenShift API ○ Enables dynamic slave images - built-in images: base, maven, nodejs - custom images OpenShift Build & Deploy with Jenkinsfile Jenkins Image Jenkinsfile Maven Image Node Image …
  • 11.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 11 OpenShift Custom Jenkins Slave Jenkinsfile podTemplate(label: "citrus", cloud: "openshift", inheritFrom: "maven", containers: [ containerTemplate(name: "jnlp", image: "toschneck/citrus-jenkins-slave", ) ]) { node('citrus') { sh "echo execute oc citrus build" checkout scm sh "mvn install" junit 'citrus-tests/target/citrus-reports/**/*.xml' archiveArtifacts "citrus-tests/target/citrus-*/**/*" } } Used by citrusframework/citrus-docker-images PR #3 FROM consol/citrus:2.7.5 ### sourced are copied from: # https://github.com/openshift/jenkins/tree/master/slave-base # https://github.com/openshift/jenkins/tree/master/slave-maven # Copy the jenkins-slave entrypoint ADD contrib/bin/* /usr/local/bin/ # Run the Jenkins JNLP client ENTRYPOINT ["/usr/local/bin/run-jnlp-client"]
  • 12.
    Build up aBuild Pipeline!
  • 13.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 13 Bakery App
  • 14.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 14 Bakery App
  • 15.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 15 Transformation to OpenShift Ziele: • Sourcecode der Apps nicht verändern • Testcode nicht verändern • Vollautomatisiert bis in die Produktion • All-in-OpenShift (CI, Build, Test, Deployment) • Jenkins v1 -> v2
  • 16.
    Stage I: CI-Buildbis zum Artefakt
  • 17.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 17 CI Build ► Docker Image build.pipeline.yml Jenkinsfile.dev Maven Image Dockerfiles OpenShift Regular Build Docker Image Artifact
  • 18.
  • 19.
  • 20.
  • 21.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 21 Mission: Integrationstest Automatisierte Schnittstellentests System Under Test Verträge Stammdaten Dienstleister Shipping JM S XM L FTP CSV Webclient Kunde Agent / Techniker Mobile, PDA Http REST Http SOAP
  • 22.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 22 Mission: Integrationstest System Under Test Stammdaten Dienstleister JM S XM L FTP CSV Kunde Agent / Techniker Http REST Http SOAP Automatisierte Schnittstellentests
  • 23.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 23 Citrus Features • Ready to use components − Client & Server • Message transports − Http REST, SOAP, JMS, FTP, TCP/IP, Mail, RMI, SSH, ... • Data formats − XML, Json, PlainText, CSV, XSD, WSDL • Test DSL − XML & Java
  • 24.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 24 Usage: Middleware Integration / ESB • Bittner&Krull KSS > 300 Tests • M-net Atlas ESB > 800 Tests • Telefonica o2 NMF, COM > 150 Tests, > 500 Tests • Vodafone UC > 250 Tests • Media Saturn ESB > 200 Tests
  • 25.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 25 more Citrus • Citrus Admin UI • Easy Testsuite Management • Reporting • Citrus Simulator • Complex Messaging Workflow Simulation • Predefined Interface Packages: WBCI, WITA
  • 26.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 26 QA -> Citrus API Integration Tests Citrus Slave Image build.pipeline.yml Jenkinsfile.qa
  • 27.
  • 28.
  • 29.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 29 Sakuli End-to-End Use Cases
  • 30.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 30 Motivation • Gründung February 2014 Open Source (Apache) • Ziele: − zwei Open Source Automation Tools „verheiraten“ − Verarbeitung der Ergebnisse an CI- u. Montioringsysteme − Plattformunabhängigkeit (Linux/Windows/MacOS) • Applikationstests mit der "Userbrille" − Funktionalität − Performance (Ladezeiten)
  • 31.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 31 Referenzen
  • 32.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 32 Component 1: Sahi / Selenium Web testing tool (sahi.co.in, seleniumhq.org) method based DOM access: _assertContainsText ("Logged in as: Sakuli", _div("user_field")); _click(_span("Loaded Run Tabels")); _assertExists(_table("cross_table_fixed")); _assertExists(_cell(“testing allowed", _rightOf(_span("Name")), _under(_cell("Action"))); <table> <tbody> <tr> <td>Alice</td> <td>Bob</td> </tr> </tbody> </table> Webserverlocalhost:9999 {js}
  • 33.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 33 Component 2: Sikuli Visual automation tool (sikuli.org) image identification, mouse & keyboard interaction: screen.find("sap_ok").click(); screen.find("sap_ok").right(40).click().type("2223"); var bubble = new Region().waitForImage("bubble.png", 20); bubble.dragAndDropTo(bubble.left(35)).highlight();
  • 34.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 34 Vergleich: Sahi/Selenium & Sikuli Sikuli universell, kompl. Bildschirm ressourcenintensiv(er) braucht "freie Sicht" Sahi / Selenium beschränkt auf web, (kein Flash, Java applets...) schnell effizient zu schreiben (Controller + Recorder)
  • 35.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 35 Mehrwert • Erlaubt den Einsatz beider Tools zugleich • Step-by-step code (JavaScript, Java) • Automatische Screenshots im Fehlerfall • Cloud-ready Docker-Images für Kubernets/OpenShift • Sakuli UI für Pflege, Ausführung und Reporting (beta) • "Forwarder"-Module: − Monitoring (Gearman, Icinga, CheckMK) − CI (Jenkins...) − Datenbanken (MySQL/MariaDB, ...)
  • 36.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 36 Monitoring Integration Service Check (OMD - Thruk)
  • 37.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 37 Sakuli End-2-End Testing Container
  • 38.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 38 QA -> tested Docker Image Docker Image Artifcat Citrus Slave Image SakuliImage build.pipeline.yml Jenkinsfile.qa
  • 39.
  • 40.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 40 Review • Jenkins wurde nicht desingend für Container/Pods Plugins, Startup, Java Agents, lokales Filesystem • Migration zu Jenkinsfiles • Viele Wrapper-Scripte, um flexibel zu sein • Verteiltes CI-Design erfordert ein Umdenken • CI-Daten schwerer zugänglich Logs, Screenshots, Artifakte • Technologie-Mix • Slave-Image intransparent -> do it your self Base Image: github.com/openshift/jenkins/slave-base • Verteilte Dokumentation OpenShift, Kubernetes, Jenkins, Jenkins-Plugins, Docker, …
  • 41.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 41 Review • Skalierung übernimmt der Cluster • "oc CLI client" anstatt Openshift-Jenkins-Plugin ► Pipeline modular test/entwickelbar • Parametrisierte YAML Templates für OpenShift • Infrastructur as Code • Neue Stages sind einfach zu erstellen • Deployment wird automatisch mitgetestet • Secrets durch Cluster-Admins verwaltbar • Builds Steuerbar von CLI und UI • Erweiterbarkeit durch OpenSource
  • 42.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 42 Alternative Ansätze hasura/gitkube ⇨ Gitkube • “git push” based Workflow on remote Git • Simple: Kombination von bash Scripts ⇨ DroneCI / KubeCI • Container first und einfache Konzept • Nutzbar für gebaute Images • Layered Build Concept für Pods (in Entwicklung) ⇨ Skaffold: • Einfacher CI/CD Workflow • 2 Stages: Local & Remote ⇨ JenkinsX • Vordefinierter Workflow für CI/CD in Kubernetes • kein neuer Jenkins -> Wrapper • GitHub only GoogleContainerTools/skaffold kubeciiodrone/drone jenkins-x/jx
  • 43.
    OpenShift-Build-Pipelines: Build ->Test -> Run! Folie 43 Links toschneck/openshift-example-bakery-ci-pipeline citrusframework/citrus www.citrusframework.org ConSol/sakuli www.sakuli.org @toschneck @citrus_test @sakuli_e2e
  • 44.
  • 45.
  • 46.
    ConSol Consulting & SolutionsSoftware GmbH Franziskanerstr. 38 D-81669 München Tel.: +49-89-45841-100 info@consol.de www.consol.de Twitter: @consol_de