Initial commit
Add infrastructure jobs for sandbox

Related-PROD: RE-336

Change-Id: I2140d47e3fc360ab05f92175b29b31e69b2ec10b
diff --git a/servers/sandbox-ci/global.yaml b/servers/sandbox-ci/global.yaml
new file mode 100644
index 0000000..34b29d3
--- /dev/null
+++ b/servers/sandbox-ci/global.yaml
@@ -0,0 +1,34 @@
+- defaults:
+    name: global
+    project-type: pipeline
+    description: '{job_description}'
+    sandbox: true
+
+    ###
+    #
+    # Global variables
+    #
+    ###
+
+    job_description: Do not edit this job through the web UI!
+
+    ci_name: 'sandbox-ci'
+    jcasc_branch: '{ci_name}'
+    k8s_cluster: unset
+    jjb_update_label: unset
+    jjb_credentials_id: jjb-update
+
+    gerrit-server: 'mcp-gerrit'
+    gerrit-host: 'gerrit.mcp.mirantis.net'
+    gerrit-port: '29418'
+    gerrit-url:  'https://gerrit.mcp.mirantis.net'
+    gerrit-git-url: 'ssh://{gerrit-host}:{gerrit-port}'
+    gerrit-custom-url: '* $JOB_NAME $BUILD_URL/consoleText'
+
+    artifactory-url:    'https://artifactory.mcp.mirantis.net'
+    artifactory_credentials_id: artifactory
+
+    git-credentials-id: '{ci_name}'
+    docker-prod-virtual: 'docker-prod-virtual.docker.mirantis.net'
+    docker-dev-local: 'docker-dev-local.docker.mirantis.net'
+    docker-dev-virtual:  'docker-dev-virtual.docker.mirantis.net'
diff --git a/servers/sandbox-ci/infra/codenarc.yaml b/servers/sandbox-ci/infra/codenarc.yaml
new file mode 100644
index 0000000..cd1b985
--- /dev/null
+++ b/servers/sandbox-ci/infra/codenarc.yaml
@@ -0,0 +1,16 @@
+---
+
+- project:
+    name: codenarc
+    jobs:
+    - common/codenarc:
+        projects:
+        - project-pattern: mcp-ci/jenkins-jobs
+          branches:
+          - branch-pattern: 'master'
+          file-paths:
+          - compare-type: ANT
+            pattern: 'common/**/*.groovy'
+          - compare-type: ANT
+            pattern: 'servers/{ci_name}/**/*.groovy'
+
diff --git a/servers/sandbox-ci/infra/gerrit-projects.yaml b/servers/sandbox-ci/infra/gerrit-projects.yaml
new file mode 100644
index 0000000..d7560a9
--- /dev/null
+++ b/servers/sandbox-ci/infra/gerrit-projects.yaml
@@ -0,0 +1,56 @@
+- project:
+    name: gerrit-projects
+    tox_env:
+    - update:
+        #gerrit_event: ref-updated-event
+        #refspec: '$GERRIT_REFNAME'
+        gerrit_event: change-merged-event
+        refspec: '$GERRIT_BRANCH'
+    - check:
+        gerrit_event: patchset-created-event
+        refspec: '$GERRIT_REFSPEC'
+    jobs:
+    - infra/gerrit-projects
+
+- job-template:
+    name: infra.gerrit-projects.{tox_env}
+    id: infra/gerrit-projects
+    project-type: pipeline
+    concurrent: False
+
+    properties:
+    - build-discarder:
+        days-to-keep: 15
+    - inject:
+        properties-content: |
+          CI_NAME={ci_name}
+          TOX_ENV={tox_env}
+          DOCKER_IMAGE={docker-infra-agent}
+          K8S_CLUSTER={k8s_cluster}
+          GIT_CREDENTIALS_ID={git-credentials-id}
+          REFSPEC={refspec}
+          JEEPYB_GERRIT_HOST={gerrit-host}
+          JEEPYB_USER=mcp-gerrit
+          JEEPYB_COMMITTER=Gerrit MCP <mcp-gerrit@mirantis.com>
+          JEEPYB_CREDENTIALS_ID=gerrit
+          ARTIFACTORY_URL={artifactory-url}
+          ART_CREDENTIALS_ID={artifactory_credentials_id}
+
+    parameters:
+    - bool:
+        name: MAINTAIN_MODE
+        default: false
+        description: Enable maintaining mode
+
+    triggers:
+    - gerrit:
+        server-name: '{gerrit-server}'
+        trigger-on:
+        - '{gerrit_event}'
+        projects:
+        - project-pattern: '{gerrit-projects-project}'
+          branches:
+          - branch-pattern: 'master'
+        custom-url: '* $JOB_NAME $BUILD_URL'
+
+    dsl: !include-raw-escape: pipelines/gerrit-projects.groovy
diff --git a/servers/sandbox-ci/infra/pipelines/gerrit-projects.groovy b/servers/sandbox-ci/infra/pipelines/gerrit-projects.groovy
new file mode 100644
index 0000000..3835ceb
--- /dev/null
+++ b/servers/sandbox-ci/infra/pipelines/gerrit-projects.groovy
@@ -0,0 +1,102 @@
+#!groovy
+
+def main() {
+    String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+    String gitRef = env.REFSPEC
+    String artInfraNamespace = 'binary-dev-local/infra'
+    String artCacheFile = "${env.CI_NAME}.jeepyb.zip"
+    String artCacheUrl = "${env.ARTIFACTORY_URL}/artifactory/${artInfraNamespace}/${artCacheFile}"
+    String artCredential = env.ART_CREDENTIALS_ID
+    String cacheHome = '.workspace'
+    def response
+
+    stage('SCM checkout') {
+        if (env.MAINTAIN_MODE.toLowerCase() == 'false') {
+            checkout \
+                $class: 'GitSCM',
+                branches: [[
+                    name: 'FETCH_HEAD'
+                ]],
+                userRemoteConfigs: [[
+                    url: gitUrl,
+                    refspec: gitRef,
+                    credentialsId: env.GIT_CREDENTIALS_ID
+                ]],
+                extensions: [[
+                    $class: 'WipeWorkspace'
+                ]]
+        }
+    }
+
+    stage('Get jeepyb cache') {
+        dir(cacheHome) {
+            response = httpRequest \
+                url: artCacheUrl,
+                authentication: artCredential,
+                httpMode: 'GET',
+                outputFile: artCacheFile,
+                validResponseCodes: '100:399,404'
+            if (response.status != 404) {
+               unzip \
+                   zipFile: artCacheFile
+            }
+        }
+    }
+
+    stage("Jeepyb-${TOX_ENV}") {
+        if (env.MAINTAIN_MODE.toLowerCase() == 'false') {
+            sshagent([env.JEEPYB_CREDENTIALS_ID]) {
+                withEnv([
+                    "HOME=${cacheHome}",
+                    'GIT_SSH_VARIANT=ssh'
+                ]) {
+                    sh 'tox -v -e ${TOX_ENV}'
+                }
+            }
+        } else {
+            input \
+                message: 'Sleeping for maintainance'
+        }
+    }
+    stage('Save jeepyb cache') {
+        dir(cacheHome) {
+            sh "rm -f ${artCacheFile}"
+            zip \
+                zipFile: artCacheFile,
+                glob: 'cache/project.cache'
+            response = httpRequest \
+                url: artCacheUrl,
+                authentication: artCredential,
+                httpMode: 'PUT',
+                multipartName: 'file',
+                uploadFile: artCacheFile
+        }
+    }
+}
+
+String podTpl = """
+    apiVersion: "v1"
+    kind: "Pod"
+    spec:
+      securityContext:
+        runAsUser: 1000
+      containers:
+      - name: "main"
+        image: "${env.DOCKER_IMAGE}"
+        command:
+        - "cat"
+        securityContext:
+          privileged: false
+        tty: true
+"""
+podTemplate(
+        cloud: env.K8S_CLUSTER,
+        yaml: podTpl,
+        showRawYaml: false
+    ) {
+        node(POD_LABEL) {
+        container('main') {
+            main()
+        }
+    }
+}
diff --git a/servers/sandbox-ci/infra/pipelines/terraform-validate.groovy b/servers/sandbox-ci/infra/pipelines/terraform-validate.groovy
new file mode 100644
index 0000000..13e0a6f
--- /dev/null
+++ b/servers/sandbox-ci/infra/pipelines/terraform-validate.groovy
@@ -0,0 +1,92 @@
+#!groovy
+
+def main() {
+    // Get & prepare source code
+    stage('SCM checkout') {
+        String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+        String gitRef = env.GERRIT_REFSPEC
+
+        checkout \
+            $class: 'GitSCM',
+            branches: [[
+                name: 'FETCH_HEAD'
+            ]],
+            userRemoteConfigs: [[
+                url: gitUrl,
+                refspec: gitRef,
+                credentialsId: env.GIT_CREDENTIALS_ID
+            ]],
+            extensions: [[
+                $class: 'WipeWorkspace'
+            ]]
+    }
+
+    stage('Terraform-lint') {
+        String changedFolders = sh \
+            script: '''
+                git show \
+                    --name-only \
+                    --diff-filter=AM \
+                    | grep '.tf\$' \
+                    | awk -F'/' '{print $1"/"$2}' \
+                    | uniq
+            ''',
+            returnStdout: true
+
+        Integer result = 0
+        changedFolders.tokenize('\n').each {
+            dir(it) {
+                withCredentials([
+                    usernamePassword(
+                        credentialsId: env.AWS_CREDENTIALS_ID,
+                        usernameVariable: 'AWS_ACCESS_KEY_ID',
+                        passwordVariable: 'AWS_SECRET_ACCESS_KEY'
+                    )
+                ]) {
+                    result += sh \
+                        script: 'terraform init',
+                        returnStatus: true
+                    result += sh \
+                        script: 'terraform validate',
+                        returnStatus: true
+                    result += sh \
+                        script: 'terraform fmt -diff -recursive -check',
+                        returnStatus: true
+                }
+            }
+        }
+        if (result > 0) {
+            currentBuild.result = 'FAILURE'
+        }
+    }
+}
+
+String podTpl = """
+    apiVersion: "v1"
+    kind: "Pod"
+    spec:
+      securityContext:
+          runAsUser: 1000
+      containers:
+      - name: "terraform-test"
+        image: "${env.DOCKER_IMAGE}"
+        command:
+        - "cat"
+        securityContext:
+          privileged: false
+        tty: true
+"""
+
+podTemplate(
+        cloud: env.K8S_CLUSTER,
+        yaml: podTpl,
+        showRawYaml: false
+    ) {
+        node(POD_LABEL) {
+        container('terraform-test') {
+            ansiColor {
+                main()
+            }
+        }
+    }
+}
diff --git a/servers/sandbox-ci/infra/shellcheck.yaml b/servers/sandbox-ci/infra/shellcheck.yaml
new file mode 100644
index 0000000..336ff85
--- /dev/null
+++ b/servers/sandbox-ci/infra/shellcheck.yaml
@@ -0,0 +1,14 @@
+---
+- project:
+    name: shellcheck
+    jobs:
+    - common/shellcheck:
+        projects:
+        - project-pattern: mcp-ci/jenkins-jobs
+          branches:
+          - branch-pattern: 'master'
+          file-paths:
+          - compare-type: ANT
+            pattern: 'common/**/*.sh'
+          - compare-type: ANT
+            pattern: 'servers/{ci_name}/**/*.sh'
diff --git a/servers/sandbox-ci/infra/terraform-validate.yaml b/servers/sandbox-ci/infra/terraform-validate.yaml
new file mode 100644
index 0000000..d79b45e
--- /dev/null
+++ b/servers/sandbox-ci/infra/terraform-validate.yaml
@@ -0,0 +1,42 @@
+---
+- project:
+    name: terraform-validate
+    jobs:
+    - infra/terraform-validate
+
+- job-template:
+    name: infra.terraform-validate
+    id: infra/terraform-validate
+    project-type: pipeline
+    description: Check terraform files by terraform validate and terraform fmt
+    concurrent: true
+
+    properties:
+    - build-discarder:
+        days-to-keep: 14
+    - inject:
+        properties-content: |
+          DOCKER_IMAGE={docker-dev-virtual}/mirantis/openstack-ci/jenkins-job-tests:latest
+          GIT_CREDENTIALS_ID={git-credentials-id}
+          AWS_CREDENTIALS_ID={aws-credentials-id}
+
+    triggers:
+    - gerrit:
+        server-name: '{gerrit-server}'
+        projects:
+        - project-compare-type: PLAIN
+          project-pattern: mcp-ci/infra
+          branches:
+          - branch-pattern: 'master'
+          file-paths:
+          - compare-type: ANT
+            pattern: 'terraform/**'
+        trigger-on:
+        - patchset-created-event:
+            exclude-drafts: True
+        custom-url: '- ${{JOB_NAME}} ${{BUILD_URL}}console'
+        skip-vote:
+          failed: false
+          notbuilt: false
+
+    dsl: !include-raw-escape: pipelines/terraform-validate.groovy
diff --git a/servers/sandbox-ci/infra/tox.yaml b/servers/sandbox-ci/infra/tox.yaml
new file mode 100644
index 0000000..78e3270
--- /dev/null
+++ b/servers/sandbox-ci/infra/tox.yaml
@@ -0,0 +1,16 @@
+---
+- project:
+    name: tox
+
+    jobs:
+    - common/tox:
+        projects:
+        - project-compare-type: PLAIN
+          project-pattern: mcp-ci/infra
+          branches:
+          - branch-compare-type: PLAIN
+            branch-pattern: master
+        skip_vote:
+          failed: false
+          notbuilt: true
+
diff --git a/servers/sandbox-ci/infra/yamllint.yaml b/servers/sandbox-ci/infra/yamllint.yaml
new file mode 100644
index 0000000..fdf0ac1
--- /dev/null
+++ b/servers/sandbox-ci/infra/yamllint.yaml
@@ -0,0 +1,20 @@
+---
+- project:
+    name: yamllint
+    yaml_paths:
+    - compare-type: REG_EXP
+      pattern: '.*\.ya?ml$'
+
+    jobs:
+    - common/yamllint:
+        projects:
+        - project-compare-type: PLAIN
+          project-pattern: mcp-ci/jenkins-config
+          branches:
+          - branch-compare-type: PLAIN
+            branch-pattern: '{ci_name}'
+          file-paths: '{obj:yaml_paths}'
+        skip_vote:
+          failed: false
+          notbuilt: true
+