diff --git a/VERSION b/VERSION
index 944880f..e4604e3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.2.0
+3.2.1
diff --git a/resources/bin/rb_sync_minio_cluster.sh b/resources/bin/rb_sync_minio_cluster.sh
deleted file mode 100644
index ccc8f0d..0000000
--- a/resources/bin/rb_sync_minio_cluster.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-#######################################################################
-# Copyright (c) 2024 ENEO TecnologĂa S.L.
-# This file is part of redBorder.
-# redBorder is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# redBorder is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License License for more details.
-# You should have received a copy of the GNU Affero General Public License License
-# along with redBorder. If not, see .
-#######################################################################
-
-source /etc/profile.d/rvm.sh
-
-/usr/lib/redborder/scripts/rb_sync_minio_cluster.rb $*
diff --git a/resources/scripts/rb_sync_minio_cluster.rb b/resources/scripts/rb_sync_minio_cluster.rb
deleted file mode 100644
index 54bef6d..0000000
--- a/resources/scripts/rb_sync_minio_cluster.rb
+++ /dev/null
@@ -1,274 +0,0 @@
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-#######################################################################
-# Copyright (c) 2024 ENEO TecnologĂa S.L.
-# This file is part of redBorder.
-# redBorder is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# redBorder is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License License for more details.
-# You should have received a copy of the GNU Affero General Public License License
-# along with redBorder. If not, see .
-#######################################################################
-
-require 'net/http'
-require 'uri'
-require 'json'
-
-module RedBorder
- # Add a logger for the RedBorder module
- module Logger
- # clean way to do puts :)
- def self.log(msg)
- puts msg
- end
- end
-
- # Module for initializing Minio replication
- module MinioReplication
- # Initializes Minio replication if the current node is the cluster leader.
- #
- # @return [void]
- def self.init_minio_replication
- return unless RedBorder::Serf.im_leader?
-
- RedBorder::Minio.set_minio_replicas
- end
- end
-
- # Module for interacting with Serf
- module Serf
- # Checks if the current node is the cluster leader.
- #
- # @return [Boolean] Returns true if the current node is the cluster leader, otherwise false.
- def self.im_leader?
- output = `serf members`
- leader = ''
- if $?.success?
- leader_node = output.lines.find { |line| line.include?('leader=ready') }
-
- leader = leader_node.split[1].split(':')[0] if leader_node
- end
-
- my_ips = `hostname -I`.split(' ')
- my_ips.include? leader
- end
-
- # Gets the name of the cluster leader.
- #
- # @return [String] The name of the cluster leader.
- def self.cluster_leader
- output = `serf members`
- leader = ''
- if $?.success?
- leader_node = output.lines.find { |line| line.include?('leader=ready') }
-
- if leader_node
- parts = leader_node.split
- leader = parts[0]
- end
- end
-
- leader
- end
- end
-
- # Module for making HTTP requests
- module HTTP
- HTTP_OPEN_TIMEOUT = 8600
- HTTP_READ_TIMEOUT = 8600
- # Sends an HTTP request.
- #
- # @param url [String] The URL to request.
- # @param method [String] The HTTP method (GET, POST, DELETE).
- # @param body [String] The request body (optional).
- # @param cookie [String] The cookie to include in the request (optional).
- # @param log [Boolean] log response (optional).
- # @return [Net::HTTPResponse] The HTTP response.
- def self.request(url, method, body = nil, cookie = nil, log: false)
- uri = URI.parse(url)
- http = Net::HTTP.new(uri.host, uri.port)
- http.read_timeout = HTTP_READ_TIMEOUT
- http.open_timeout = HTTP_OPEN_TIMEOUT
-
- request_class = { 'POST' => Net::HTTP::Post, 'DELETE' => Net::HTTP::Delete }[method.upcase] || Net::HTTP::Get
- request = request_class.new(uri.request_uri)
- request['Content-Type'] = 'application/json' if body
- request['Cookie'] = cookie if cookie
- request.body = body if body
-
- response = http.request(request)
- RedBorder::Logger.log(response.body) if log
-
- response
- end
- end
-
- # Module for interacting with Consul
- module Consul
- CONSUL_ENDPOINT = 'http://127.0.0.1:8500'
-
- # Retrieves S3 nodes from Consul.
- #
- # @return [Array] An array of hashes containing S3 node information.
- # Each hash contains keys :name, :console_endpoint, and :api_endpoint.
- def self.s3_nodes_from_consul
- response = RedBorder::HTTP.request("#{CONSUL_ENDPOINT}/v1/catalog/service/s3", 'GET')
- JSON.parse(response.body).map do |node|
- {
- name: node['Node'],
- console_endpoint: "http://#{node['Address']}:9000",
- api_endpoint: "http://#{node['Address']}:9001"
- }
- end
- end
- end
-
- # Module for interacting with Minio
- module Minio
- MINIO_CONFIG_PATH = '/etc/default/minio'
- LOCAL_MINIO_ENDPOINT = 'http://127.0.0.1:9001'
- MINIO_USER_KEY = 'MINIO_ROOT_USER='
- MINIO_ROOT_PASSWORD = 'MINIO_ROOT_PASSWORD='
- BUCKET = 'bucket'
- MINIMUM_MINIO_HOSTS = 1
- CLEAN_S3_DEF_BODY = [{ 'path' => '/', 'versionID' => '', 'recursive' => true }].to_json
-
- # Retrieves the Minio session ID.
- #
- # @param host [String] The Minio host.
- # @return [String] The Minio session ID.
- def self.minio_session_id(host = LOCAL_MINIO_ENDPOINT)
- credentials = RedBorder::Minio.minio_credentials
-
- body = {
- accessKey: credentials[:accessKey],
- secretKey: credentials[:secretKey]
- }.to_json
-
- response = RedBorder::HTTP.request("#{host}/api/v1/login", 'POST', body)
- response['Set-Cookie']
- end
-
- # Retrieves Minio credentials.
- #
- # @return [Hash] Minio credentials containing :accessKey and :secretKey.
- def self.minio_credentials
- credentials = {}
- File.foreach(MINIO_CONFIG_PATH) do |line|
- if line.start_with?(MINIO_USER_KEY)
- credentials[:accessKey] = line.split('=').last.strip
- elsif line.start_with?(MINIO_ROOT_PASSWORD)
- credentials[:secretKey] = line.split('=').last.strip
- end
- end
- credentials
- end
-
- # Cleans S3 replication.
- #
- # @return [Net::HTTPResponse] The HTTP response.
- def self.clean_s3_replication
- RedBorder::Logger.log('Cleaning S3 replications...')
- hosts = RedBorder::Consul.s3_nodes_from_consul
- cookie = RedBorder::Minio.minio_session_id
- names = hosts.map { |node| node[:name] }
-
- body = {
- 'all' => true,
- 'sites' => names
- }.to_json
-
- RedBorder::HTTP.request("#{LOCAL_MINIO_ENDPOINT}/api/v1/admin/site-replication", 'DELETE', body, cookie)
- end
-
- # Cleans S3 slave buckets.
- #
- # @return [void]
- def self.clean_s3_slaves_buckets
- RedBorder::Logger.log('Cleaning S3 Slaves Buckets...')
- hosts = RedBorder::Consul.s3_nodes_from_consul
- hosts.each do |host|
- next if RedBorder::Serf.cluster_leader == host[:name]
-
- cookie = RedBorder::Minio.minio_session_id host[:api_endpoint]
-
- RedBorder::HTTP.request("#{host[:api_endpoint]}/api/v1/buckets/bucket/delete-objects?all_versions=true",
- 'POST', CLEAN_S3_DEF_BODY, cookie)
- end
- end
-
- # Deletes S3 slave buckets.
- #
- # @return [void]
- def self.delete_s3_slaves_buckets
- RedBorder::Logger.log('Deleting S3 Slaves Buckets...')
- hosts = RedBorder::Consul.s3_nodes_from_consul
- hosts.each do |host|
- next if RedBorder::Serf.cluster_leader == host[:name]
-
- cookie = RedBorder::Minio.minio_session_id host[:api_endpoint]
-
- body = { 'name' => BUCKET }.to_json
-
- RedBorder::HTTP.request("#{host[:api_endpoint]}/api/v1/buckets/#{BUCKET}", 'DELETE', body, cookie)
- end
- end
-
- # Restarts Minio.
- #
- # @return [void]
- def self.restart
- RedBorder::Logger.log('Restarting Minio Service (master)')
- system('service minio restart > /dev/null 2>&1')
- system('sleep 30')
- end
-
- # Initializes cluster synchronization by performing the following steps:
- # 1. Restart Minio service on the master node.
- # 2. Clean S3 replication configurations.
- # 3. Clean S3 buckets on slave nodes.
- # 4. Delete S3 buckets on slave nodes.
- # 5. Fetches information about S3 hosts from Consul.
- # 6. Retrieves Minio session ID (cookie).
- # 7. Retrieves Minio credentials.
- #
- # @return [Hash] A hash containing information about the initialized cluster synchronization.
- def self.init_cluster_sync
- RedBorder::Minio.restart
- RedBorder::Minio.clean_s3_replication
- RedBorder::Minio.clean_s3_slaves_buckets
- RedBorder::Minio.delete_s3_slaves_buckets
- {
- hosts: RedBorder::Consul.s3_nodes_from_consul,
- cookie: RedBorder::Minio.minio_session_id,
- credentials: RedBorder::Minio.minio_credentials
- }
- end
-
- # Sets Minio replicas.
- #
- # @return [Net::HTTPResponse] The HTTP response.
- def self.set_minio_replicas
- cluster_data = RedBorder::Minio.init_cluster_sync
-
- body = cluster_data[:hosts].map do |host|
- { accessKey: cluster_data[:credentials][:accessKey], secretKey: cluster_data[:credentials][:secretKey],
- name: host[:name], endpoint: host[:console_endpoint] }
- end.to_json
-
- return unless cluster_data[:hosts].size > MINIMUM_MINIO_HOSTS
-
- RedBorder::HTTP.request("#{LOCAL_MINIO_ENDPOINT}/api/v1/admin/site-replication", 'POST', body,
- cluster_data[:cookie], log: true)
- end
- end
-end
-
-# Initialize Minio replication
-RedBorder::MinioReplication.init_minio_replication