diff --git a/src/com/mirantis/mcp/CCP.groovy b/src/com/mirantis/mcp/CCP.groovy
deleted file mode 100644
index b90d5d4..0000000
--- a/src/com/mirantis/mcp/CCP.groovy
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.mirantis.mcp
-
-def checkPortIsFree(String localPort) {
-    withEnv(["port=${localPort}"]) {
-        sh '''
-            if netstat -pnat | grep -qw "${port}"; then
-                echo "Port ${port} is already opened."
-                exit 1
-            fi
-        '''
-    }
-}
-
-def deployProxy(String confDir, String proxyPassURL, String localPort) {
-    withEnv(["localPort=${localPort}",
-             "proxyPassURL=${proxyPassURL}",
-             "confDir=${confDir}"]) {
-        sh '''\
-            cat <<EOF > "${confDir}/nginx-${localPort}"
-            worker_processes auto;
-            user jenkins;
-            pid ${confDir}/nginx-${localPort}.pid;
-            error_log /dev/null;
-            #
-            events {
-               worker_connections 768;
-            }
-            #
-            http {
-                sendfile on;
-                tcp_nopush on;
-                tcp_nodelay on;
-                keepalive_timeout 65;
-                types_hash_max_size 2048;
-                #
-                include /etc/nginx/mime.types;
-                default_type application/octet-stream;
-                #
-                access_log off;
-                #
-                server {
-                    listen ${localPort} default_server;
-                    #
-                    server_name _;
-                    client_max_body_size 0;
-                    # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
-                    chunked_transfer_encoding on;
-                    #
-                    location / {
-                        proxy_set_header  Host              \\$http_host;   # required for docker client's sake
-                        proxy_set_header  X-Real-IP         \\$remote_addr; # pass on real client's IP
-                        proxy_set_header  X-Forwarded-For   \\$proxy_add_x_forwarded_for;
-                        proxy_set_header  X-Forwarded-Proto \\$scheme;
-                        proxy_read_timeout                  900;
-                        proxy_pass                          ${proxyPassURL} ;
-                    }
-                }
-            }'''.stripIndent()
-        }
-    sh "nginx -t -c ${confDir}/nginx-${localPort}"
-    sh "nginx -c ${confDir}/nginx-${localPort}"
-    return "127.0.0.1:${localPort}"
-}
-
-def destroyProxy(String confDir, String localPort) {
-    def proxyPid = sh(script: "cat ${confDir}/nginx-${localPort}.pid",
-                      returnStdout: true).trim()
-    if ( proxyPid ) {
-        sh "kill -QUIT ${proxyPid}"
-    }
-}
diff --git a/src/com/mirantis/mcp/CCPCICD.groovy b/src/com/mirantis/mcp/CCPCICD.groovy
deleted file mode 100644
index 029b334..0000000
--- a/src/com/mirantis/mcp/CCPCICD.groovy
+++ /dev/null
@@ -1,373 +0,0 @@
-package com.mirantis.mcp
-
-/*
-  Example usage:
-
-  def ccpCiCd = new com.mirantis.mcp.CCPCICD().newInstance(this, env)
-
-  ccpCiCd.applyPipelineParameters()
-
-  ccpCiCd.fetchEnvConfiguration()
-  ccpCiCd.parametrizeConfig()
-
-  ccpCiCd.build()
-  ccpCiCd.deploy()
-  ccpCiCd.cleanup()
-*/
-
-/*
-  Since groovy-cps demands that local variables may be serialized,
-  any locally defined classes must also be serializable
-
-  More details: https://issues.jenkins-ci.org/browse/JENKINS-32213
-*/
-
-public class ccpCICD implements Serializable {
-
-  /*
-    Endless loop in DefaultInvoker.getProperty when accessing field
-    via getter/setter without @
-
-    This issue fixed in groovy pipeline plugin 2.25
-
-    More details https://issues.jenkins-ci.org/browse/JENKINS-31484
-  */
-
-  /*
-    nodeContext - is a context of which node the job is executed
-    through this context, CCPCICD class able to use
-    dir() writeFile() sh() and other workflow basic steps
-
-    See more https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/
-
-    nodeContext must be passed in class constructor
-  */
-  def nodeContext = null
-
-  /*
-    Job parameters are accessed through environment
-  */
-  def env = null
-
-  /*
-    Directory where stored environment configuration
-  */
-  def envConfigurationPath = null
-  def File envConfiguration = null
-
-  /*
-    Path to entry point yaml in environment directory
-  */
-  def ccpConfigPath = null
-
-  def File virtualEnv = null // Currently not supported
-
-  def URI configurationRepo = null
-
-  /*
-    parsed `ccp config dump` output
-  */
-
-  def Map ccpConfig = null
-
-  /*
-    Part of ccp parameters which will be overwritten by job
-    parametrizeConfig() method
-
-  */
-  def Map ciConfig = [
-    'registry'    : [
-      'address'   : null,
-      'username'  : null,
-      'password'  : null,
-    ],
-    'kubernetes'  : [
-      'namespace' : 'ccp',
-      'server'    : null,
-      'insecure'  : true,
-      'username'  : null,
-      'password'  : null
-    ],
-    'repositories': [
-      'path'      : null
-    ]
-
-  ]
-
-  // Using loadYAML and dumpYAML from common library
-  def common = new com.mirantis.mcp.Common()
-
-  // default CCP repo (using in upgrade)
-  def URI ccpSource = new URI('git+https://gerrit.mcp.mirantis.net/ccp/fuel-ccp')
-
-  def public void setConfURL(URI confURI) {
-    if (confURI == null) {
-      throw new IllegalArgumentException('Invalid argument')
-    }
-    this.@configurationRepo = confURI
-  }
-
-  def public URI getConfURL() {
-    return this.@configurationRepo
-  }
-
-  /*
-    According JENKINS-31314 constructor can be used only for assignments properties
-    More details: https://issues.jenkins-ci.org/browse/JENKINS-31314
-  */
-  def public ccpCICD(nodeContext, env) {
-    this.@nodeContext = nodeContext
-    this.@env = env
-  }
-
-  /*
-    Transform jenkins job arguments to ccp configuration
-    Parameters can be overriden with customParameters Map
-
-    Example usage:
-    applyPipelineParameters([
-
-      'images': [
-        'image_specs': [
-            'etcd': [
-                'tag': '41a45e5a9db5'
-            ]
-        ]
-      ]
-
-    ])
-
-  */
-
-  def public void applyPipelineParameters(Map customParameters = null) {
-
-    if (this.@env.CONF_GERRIT_URL != null) {
-      this.setConfURL(new URI(this.@env.CONF_GERRIT_URL))
-    }
-
-
-    if (this.@env.CONF_ENTRYPOINT != null) {
-      this.setCcpConfigPath(new File(this.@env.CONF_ENTRYPOINT))
-    }
-
-    if (this.@env.KUBERNETES_URL != null) {
-      this.setKubernetesURL(new URI(this.@env.KUBERNETES_URL), this.@env.CREDENTIALS_ID)
-    } else {
-      this.@ciConfig.remove('kubernetes')
-    }
-
-    if (this.@env.DOCKER_REGISTRY != null) {
-      this.setRegistry(new URI(this.@env.DOCKER_REGISTRY), this.env.DOCKER_REGISTRY_CREDENTIAL_ID ? this.env.DOCKER_REGISTRY_CREDENTIAL_ID : 'artifactory')
-    } else {
-      this.@ciConfig.remove('registry')
-    }
-
-
-    this.@ciConfig['repositories']['path'] = env.WORKSPACE + '/repos'
-
-    if (customParameters != null) {
-      this.@ciConfig = this.@ciConfig + customParameters
-    }
-  }
-
-  def public File getCcpConfigPath() {
-    return this.@ccpConfigPath
-  }
-
-  def public void setCcpConfigPath(File configPath) {
-    this.@ccpConfigPath = configPath
-  }
-
-  /*
-    Set k8s endpoint and credentials
-
-    Example usage:
-      this.setKubernetesURL(new URI('https://host:443'), 'kubernetes-api')
-  */
-
-  def public void setKubernetesURL(URI kubernetesURL, String credentialId) {
-    if (credentialId != null) {
-      this.@nodeContext.withCredentials([
-        [
-          $class           : 'UsernamePasswordMultiBinding',
-          credentialsId    :  credentialId,
-          passwordVariable : 'K8S_PASSWORD',
-          usernameVariable : 'K8S_USERNAME'
-        ]
-      ]) {
-        this.@ciConfig['kubernetes']['username'] = env.K8S_USERNAME
-        this.@ciConfig['kubernetes']['password'] = env.K8S_PASSWORD
-      }
-    }
-
-    /*
-    //TODO(sryabin) properly parse return from getUserInfo()
-    if (kubernetesURL.getUserInfo()) {
-        this.@ciConfig['kubernetes']['username'] = kubernetesURL.getUserInfo()
-    }
-    */
-
-    this.@ciConfig['kubernetes']['server'] = kubernetesURL.toString()
-  }
-
-  def public void setRegistry(String registryEndpoint, String credentialId) {
-    if (credentialId) {
-      this.@nodeContext.withCredentials([
-        [
-          $class           : 'UsernamePasswordMultiBinding',
-          credentialsId    :  credentialId,
-          passwordVariable : 'REGISTRY_PASSWORD',
-          usernameVariable : 'REGISTRY_USERNAME'
-        ]
-      ]) {
-        this.@ciConfig['registry']['username'] = env.REGISTRY_USERNAME
-        this.@ciConfig['registry']['password'] = env.REGISTRY_PASSWORD
-      }
-    } else {
-      this.@ciConfig['registry'].remove('username')
-      this.@ciConfig['registry'].remove('password')
-    }
-
-    this.@ciConfig['registry']['address'] = registryEndpoint;
-  }
-
-  def public setEnvConfigurationDir() {
-    // TODO(sryabin) cleanup this dir in desctructor
-    this.@envConfigurationPath = File.createTempDir(this.@env.WORKSPACE + '/envConfiguration', 'ccpci')
-  }
-
-  def public File getEnvConfigurationDir() {
-    return this.@envConfigurationPath
-  }
-
-
-
-  def public File fetchEnvConfiguration() {
-
-    def gitTools = new com.mirantis.mcp.Git()
-
-    this.setEnvConfigurationDir()
-
-    gitTools.gitSSHCheckout ([
-        credentialsId : this.@env.CONF_GERRIT_CREDENTIAL_ID,
-        branch : "master",
-        host : this.getConfURL().getHost(),
-        port : this.getConfURL().getPort(),
-        project: this.getConfURL().getPath(),
-        targetDir: this.getEnvConfigurationDir().toString()
-    ])
-
-    return this.getEnvConfigurationDir()
-  }
-
-  def public String configDump() {
-    return this.ccpExecute('config dump')
-  }
-
-  /*
-    merge ccp configuration from repo and custom parameters from job arguments
-  */
-  def public Map parametrizeConfig() {
-    this.fetchEnvConfiguration()
-    this.@ccpConfig = this.@common.loadYAML(this.configDump())
-    this.setCcpConfigPath(new File('parametrized.yaml'));
-    this.@nodeContext.writeFile file: this.getEnvConfigurationDir().toString() + '/' + this.getCcpConfigPath().toString(), \
-      text: this.@common.dumpYAML(this.@ccpConfig + this.@ciConfig)
-  }
-
-  def public Map getConfig() {
-    return this.@ccpConfig
-  }
-
-
-  /*
-    Example usage:
-      ci.ccpExecute('config dump')
-  */
-  def public String ccpExecute(args) {
-    // TODO(sryabin) pass custom args from class property, like debug
-    def String output = null;
-    this.@nodeContext.dir(this.getEnvConfigurationDir().toString()) {
-      output = this.@nodeContext.sh(
-        script: "PYTHONWARNINGS='ignore:Unverified HTTPS request' ccp --config-file " + this.getCcpConfigPath().toString() +  " ${args}",
-        returnStdout: true
-      )
-    }
-    return output
-  }
-
-  /*
-    Update fuel-ccp
-
-    @param virtualEnv File, path to python virtual environment, currently not supported
-    @param source URI, if not present, use upstream
-    @param upgradePip Boolean, upgrade pip if required
-
-    Usage example:
-      upgradeCcp(new File('/home/ubuntu/.venv'), new URI('http://github.com/openstack/fuel-ccp'))
-  */
-  def public void upgradeCcp(File virtualEnv = null, URI source, Boolean upgradePip = false) {
-    if (virtualEnv) {
-      throw new UnsupportedOperationException('Python virtual environments not implemented')
-    }
-
-    try {
-      def output = this.@nodeContext.sh(
-        script: 'pip install --user --upgrade ' + ((source != null) ? source : this.@ccpSource).toString(),
-        returnStdout: true
-      )
-    } catch (e) {
-      // TODO(sryabin) catch in stderr "You should consider upgrading via the 'pip install --upgrade pip' command."
-      if (upgradePip == true) {
-        this.@nodeContext.sh(
-          script: 'pip install --upgrade pip',
-          returnStdout: true
-        )
-      }
-      // FIXME(sryabin) infinity loop
-      //this.upgradeCcp(virtualEnv, source, false)
-    }
-  }
-  def public void upgradeCcp() {
-    this.upgradeCcp(null, null, true)
-  }
-
-  def build() {
-    //TODO(sryabin) implement build -c functionality
-    return this.ccpExecute('build')
-  }
-
-  def deploy() {
-    //TODO(sryabin) implement build -c functionality
-    return this.ccpExecute('deploy')
-  }
-
-  def cleanup() {
-    try {
-      this.ccpExecute('cleanup')
-    } catch (err) {
-      this.ccpExecute('cleanup --skip-os-cleanup')
-    }
-  }
-
-  def fetch() {
-    // TODO(sryabin) implement fetch -f functioanlity
-    return this.ccpExecute('fetch')
-  }
-}
-
-/*
-  Workaround for scope limitation, and
-    org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified new
-
-  def ccpCiCd = new com.mirantis.mcp.CCPCICD()
-  def CCPCICD ci = new ccpCiCd.ccpCICD(this, env) return no such CCPCICD()
-
-  Example usage:
-    def ccpCiCd = new com.mirantis.mcp.CCPCICD().newInstance(this, env)
-
-*/
-
-def newInstance(nodeContext, env) {
-  return new ccpCICD(nodeContext,env)
-}
