Merge "Update git mirror to work with http creds"
diff --git a/src/com/mirantis/mk/Artifactory.groovy b/src/com/mirantis/mk/Artifactory.groovy
index 73ed80f..a840956 100644
--- a/src/com/mirantis/mk/Artifactory.groovy
+++ b/src/com/mirantis/mk/Artifactory.groovy
@@ -9,14 +9,15 @@
 /**
  * Make generic call using Artifactory REST API and return parsed JSON
  *
- * @param art   Artifactory connection object
- * @param uri   URI which will be appended to artifactory server base URL
+ * @param art       Artifactory connection object
+ * @param uri       URI which will be appended to artifactory server base URL
  * @param method    HTTP method to use (default GET)
  * @param data      JSON data to POST or PUT
  * @param headers   Map of additional request headers
+ * @param prefix    Default prefix "/api"
  */
-def restCall(art, uri, method = 'GET', data = null, headers = [:]) {
-    def connection = new URL("${art.url}/api${uri}").openConnection()
+def restCall(art, uri, method = 'GET', data = null, headers = [:], prefix = '/api') {
+    def connection = new URL("${art.url}${prefix}${uri}").openConnection()
     if (method != 'GET') {
         connection.setRequestMethod(method)
     }
@@ -84,6 +85,18 @@
 }
 
 /**
+ * Make PUT request using Artifactory REST API for helm charts
+ *
+ * @param art       Artifactory connection object
+ * @param uri       URI which will be appended to artifactory server base URL
+ * @param data      JSON Data to PUT
+ * @param prefix    Default prefix "/api" (empty values should be for this way)
+ */
+def restPut2(art, uri, prefix,  data = null) {
+    return restCall(art, uri, 'PUT', data, ['Accept': '*/*'], prefix)
+}
+
+/**
  * Make DELETE request using Artifactory REST API
  *
  * @param art   Artifactory connection object
@@ -107,9 +120,9 @@
 /**
  * Query artifacts by properties
  *
- * @param art   Artifactory connection object
+ * @param art           Artifactory connection object
  * @param properties    String or list of properties in key=value format
- * @param repo  Optional repository to search in
+ * @param repo          Optional repository to search in
  */
 def findArtifactByProperties(art, properties, repo) {
     query = parseProperties(properties)
@@ -444,7 +457,7 @@
  * @param chartName     Chart name
  */
 def publishArtifactoryHelmChart(art, repoName, chartName){
-    return restPut(art, "/repositories/${repoName}", "${chartName}")
+    return restPut2(art, "/${repoName}", "${chartName}")
 }
 
 /**
diff --git a/src/com/mirantis/mk/Galera.groovy b/src/com/mirantis/mk/Galera.groovy
index 382a72f..e6a34c1 100644
--- a/src/com/mirantis/mk/Galera.groovy
+++ b/src/com/mirantis/mk/Galera.groovy
@@ -396,4 +396,37 @@
 def restoreGaleraDb(env) {
     common.warningMsg("This method was renamed to 'restoreGaleraCluster'. Please change your pipeline to use this call instead! If you think that you really wanted to call 'restoreGaleraDb' you may be missing 'targetNode' parameter in you call.")
     return restoreGaleraCluster(env)
+}
+
+/**
+ * Start first node in mysql cluster. Cluster members stay removed in mysql config, additional service restart will be needed once all nodes are up.
+ * https://docs.mirantis.com/mcp/q4-18/mcp-operations-guide/tshooting/
+ * tshoot-mcp-openstack/tshoot-galera/restore-galera-cluster/
+ * restore-galera-manually.html#restore-galera-manually
+ *
+ * @param env             Salt Connection object or pepperEnv
+ * @param target  last stopped Galera node
+ * @return                output of salt commands
+ */
+def startFirstNode(env, target) {
+    def salt = new com.mirantis.mk.Salt()
+    def common = new com.mirantis.mk.Common()
+
+    // make sure that gcom parameter is empty
+    salt.cmdRun(env, target, "sed -i '/wsrep_cluster_address/ s/^#*/#/' /etc/mysql/my.cnf")
+    salt.cmdRun(env, target, "sed -i '/wsrep_cluster_address/a wsrep_cluster_address=\"gcomm://\"' /etc/mysql/my.cnf")
+
+    // start mysql service on the last node
+    salt.runSaltProcessStep(env, target, 'service.start', ['mysql'])
+
+    // wait until mysql service on the last node is up
+
+    common.retry(30, 10) {
+        value = getWsrepParameters(env, target, 'wsrep_evs_state')
+        if (value['wsrep_evs_state'] == 'OPERATIONAL') {
+            common.infoMsg('WSREP state: OPERATIONAL')
+        } else {
+            throw new Exception("Mysql service is not running please fix it.")
+        }
+    }
 }
\ No newline at end of file