亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java對接ansible自動運維化平臺方式

 更新時間:2023年04月04日 08:54:43   作者:猛男的溫柔  
這篇文章主要介紹了Java對接ansible自動運維化平臺方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Java對接ansible自動運維化平臺實現(xiàn)文件采集分發(fā)

經(jīng)過大量查閱,網(wǎng)上使用Java對接ansible自動運維化平臺的示例代碼幾乎沒有,為了方便自己后期鞏固以及有需要的小伙伴,特以記錄!?。?/p>

此次對接主要為以下兩個功能:

  • 文件采集(對文件進行批量操作,包括批量從多臺主機中采集共性文件如日志文件)
  • 文件分發(fā)(對文件進行批量操作,包括批量從多臺主機中分發(fā)共性文件如日志文件)

場景說明及ansible yum安裝

因ansible沒有Windows的安裝包,所以為了方便測試,搭建了一套Linux環(huán)境進行后續(xù)工作。

此次采用yum方式安裝,在采用yum方式安裝Ansible,首先安裝EPEL源。

yum install -y http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

查看EPEL源中的Ansible版本

yum info ansible

直接安裝此版本,如果有其他要求,請調(diào)整源,安裝其他ansible版本

yum install -y ansible

安裝完成之后,查看ansible版本信息

ansible --version

配置Ansible服務(wù)器清單

清單文件/etc/ansible/hosts,在此文件中編寫節(jié)點主機的對應(yīng)IP地址和端口

我這里只是做一個演示,其中IP后面可以添加節(jié)點真實的SSH的端口,在定義的內(nèi)容上面有一個[]列表,里面的內(nèi)容為自定義內(nèi)容,方面為了操作綁定的節(jié)點主機,我習慣稱之為分組列表

簡單的認證一下,Ping一下添加的主機

成功安裝ansible ??!

Java代碼實現(xiàn)文件分發(fā)

顧名思義,文件分發(fā)就是把本機的文件分發(fā)到多個主機。

這時候就需要 Apache POI(大家可以去導入對應(yīng)的包)來創(chuàng)建本機的文件了(ansible Host配置文件也通過POI創(chuàng)建)

POI創(chuàng)建文件工具類

package com.tiduyun.cmp.operation.utils;

import com.tiduyun.cmp.common.model.operation.HostInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author huyuan@tiduyun.com ansible創(chuàng)建文件
 */
@Slf4j
@Component
public class AnsibleCreateFileUtils {
    private final static String filename = "hosts";

    public static String passWordConnect(List<HostInfo> hostInfo, String hostGroup , String directory) throws IOException{
        /** 在本地新建一個文件夾 里面創(chuàng)建一個文件 向里面寫入內(nèi)容 */


        // 創(chuàng)建文件夾對象 創(chuàng)建文件對象
        File folder = new File(directory);
        // 如果文件夾不存在 就創(chuàng)建一個空的文件夾
        if (!folder.exists()) {
            log.info("創(chuàng)建了文件夾{}" , folder);
            folder.mkdirs();
        }
        File file = new File(directory, filename);
        // 如果文件不存在 就創(chuàng)建一個空的文件
        if (!file.exists()) {
            try {
                log.info("創(chuàng)建了文件{}" , file);
                file.createNewFile();
            } catch (IOException e) {
                log.error("error data{}" , e);
            }
        }
        // 寫入數(shù)據(jù)
        // 創(chuàng)建文件字節(jié)輸出流
        FileOutputStream fos = new FileOutputStream(file);
        try {
            List<String> list = new ArrayList<>();
            for (HostInfo data : hostInfo) {
                // 開始寫
                String string = data.getHost() + " ansible_ssh_pass=" + data.getPasswd() + " ansible_ssh_user="
                    + data.getAccount() + " ansible_ssh_port=" + data.getPort();
                list.add(string);
            }
            String splicingData = StringUtils.join(list, "\n");
            String str = "[" + hostGroup + "]" + "\n" + splicingData;
            byte[] bytes = str.getBytes();
            // 將byte數(shù)組中的所有數(shù)據(jù)全部寫入
            fos.write(bytes);
            fos.flush();
            log.info("文件內(nèi)容{}" , str);
            // 刪除文件
            // deleteFile(file);
            // 關(guān)閉流

        } catch (IOException e) {
            log.error("error data{}" , e);
            throw e;
        }finally {
            if (fos != null) {
                fos.close();
            }
        }
        return directory;
    }

    public static void deleteFile(File file) {
        if (file.exists()) {// 判斷路徑是否存在
            if (file.isFile()) {// boolean isFile():測試此抽象路徑名表示的文件是否是一個標準文件。
                file.delete();
            } else {// 不是文件,對于文件夾的操作
                    // 保存 路徑D:/1/新建文件夾2 下的所有的文件和文件夾到listFiles數(shù)組中
                File[] listFiles = file.listFiles();// listFiles方法:返回file路徑下所有文件和文件夾的絕對路徑
                for (File file2 : listFiles) {
                    /*
                     * 遞歸作用:由外到內(nèi)先一層一層刪除里面的文件 再從最內(nèi)層 反過來刪除文件夾
                     *    注意:此時的文件夾在上一步的操作之后,里面的文件內(nèi)容已全部刪除
                     *         所以每一層的文件夾都是空的  ==》最后就可以直接刪除了
                     */
                    deleteFile(file2);
                }
            }
            file.delete();
        } else {
            log.error("該file路徑不存在!!");
        }

    }
}

創(chuàng)建主機組配置文件

:ansible分為兩種連接方式,這里采用的是密鑰連接,生成的文件已拼接密鑰?。。『罄m(xù)的采集與分發(fā)都要用到這個。(如有不懂的小伙伴,可以去查找一下ansible的連接方式)

    @Override
    public void ansibleCreateHost(HostInfo hostInfo, String Key) {
        ParamCheckUtils.notNull(hostInfo, "hostInfo");

        List<HostInfo> HostIp = Arrays.asList(hostInfo);
        for (HostInfo data : HostIp) {
            String ansiblePassWd = data.getPasswd();
            String PassWd = hostInfoService.decode(ansiblePassWd);
            data.setPasswd(PassWd);
        }
        try {
            AnsibleCreateFileUtils.passWordConnect(HostIp, ansibleConfigurationItemVo.getHostGroup(),
                ansibleConfigurationItemVo.getDirectory());
        } catch (IOException e) {
            log.error("Failed to create host configuration{}", e);
        }
    }

實現(xiàn)文件分發(fā)

主機配置文件已經(jīng)配置好,接下來就是執(zhí)行ansible對應(yīng)的命令,通過Java拼接ansible命令。

執(zhí)行命令工具類



package com.tiduyun.cmp.operation.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

import static cn.hutool.db.DbUtil.close;

/**
 * @author huyuan@tiduyun.com ansible執(zhí)行命令工具類
 * upload 上傳文件
 * createRemoteDirectory  創(chuàng)建遠程目錄
 */
@Slf4j
public class AnsibleExecuteTheOrderUtils {

    private final static String commandBin = "/bin/sh";

    private final static String commandC = "-c";


    /**
     *  創(chuàng)建遠程目錄
     */
    public static void createRemoteDirectory(String hostGroup, String remotePath, String directory) throws IOException {
        Runtime run = Runtime.getRuntime();
        String[] cmds = new String[3];
        cmds[0] = commandBin;
        cmds[1] = commandC;
        cmds[2] =
                "ansible " + hostGroup + " -m command -a " + "\"mkdir " + remotePath + "\"" + " -i " + directory + "/hosts";

        // 執(zhí)行CMD命令
        Process p = run.exec(cmds);
        log.info("ansible遠程執(zhí)行命令為{}", cmds[2]);

        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.forName("UTF-8")));
        try {
            String lineMes;
            while ((lineMes = br.readLine()) != null)
                log.info(lineMes);// 打印輸出信息
            try {
                // 檢查命令是否執(zhí)行失敗。
                if (p.waitFor() != 0) {
                    if (p.exitValue() == 1)// 0表示正常結(jié)束,1:非正常結(jié)束
                        log.error("命令執(zhí)行失敗");
                }
            } catch (InterruptedException e) {
                log.error("error data{}", e);
            }
        } catch (IOException e) {
            log.error("fail to carry out command{}", e);
            throw e;
        } finally {
            if (br != null) {
                br.close();
            }
        }

    }

    /**
     *  文件分發(fā)
     */
    public static void upload(String hostGroup, String localPath, String remotePath, String directory)
        throws IOException {
        Runtime run = Runtime.getRuntime();
        String[] cmds = new String[3];
        cmds[0] = commandBin;
        cmds[1] = commandC;
        cmds[2] = "ansible " + hostGroup + " -m copy -a " + "\"src=" + localPath + " dest=" + remotePath + "\"" + " -i "
            + directory + "/hosts";
        // 執(zhí)行CMD命令
        Process p = run.exec(cmds);
        log.info("ansible命令為{}", cmds[2]);

        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.forName("UTF-8")));
        try {
            String lineMes;
            while ((lineMes = br.readLine()) != null)
                log.info("ansible輸出信息為 :" + lineMes);// 打印輸出信息
            try {
                // 檢查命令是否執(zhí)行失敗。
                if (p.waitFor() != 0) {
                    if (p.exitValue() == 1)// 0表示正常結(jié)束,1:非正常結(jié)束
                        log.error("命令執(zhí)行失敗");
                }
            } catch (InterruptedException e) {
                log.error("error data{}", e);
            }
        } catch (IOException e) {
            log.error("fail to carry out command{}", e);
            throw e;
        } finally {
            if (br != null) {
                br.close();
            }
        }

    }

    /**
     *  文件采集
     */
    public static void fileCollection(String hostGroup, String remotePath, String localPath , String directory) throws IOException {
        Runtime run = Runtime.getRuntime();
        String[] cmds = new String[3];
        cmds[0] = commandBin;
        cmds[1] = commandC;
        cmds[2] = "ansible " + hostGroup + " -m fetch -a " + "\"src=" + remotePath + " dest=" + localPath + " force=yes backup=yes\"" + " -i "
                + directory + "/hosts";

        // 執(zhí)行CMD命令
        Process p = run.exec(cmds);
        log.info("ansible遠程采集文件命令為{}", cmds[2]);

        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.forName("UTF-8")));
        try {
            String lineMes;
            while ((lineMes = br.readLine()) != null)
                log.info(lineMes);// 打印輸出信息
            try {
                // 檢查命令是否執(zhí)行失敗。
                if (p.waitFor() != 0) {
                    if (p.exitValue() == 1)// 0表示正常結(jié)束,1:非正常結(jié)束
                        log.error("命令執(zhí)行失敗");
                }
            } catch (InterruptedException e) {
                log.error("error data{}", e);
            }
        } catch (IOException e) {
            log.error("fail to carry out command{}", e);
            throw e;
        } finally {
            if (br != null) {
                br.close();
            }
        }

    }

    public static void ExecuteTheOrder(String command) throws IOException {
        log.info("start execute cmd {}", command);

        String[] cmd = new String[] {"/bin/bash", "-c", command};
        Runtime run = Runtime.getRuntime();
        Process p = run.exec(cmd); // 執(zhí)行CMD命令

        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.forName("UTF-8")));
        try {
            String lineMes;
            while ((lineMes = br.readLine()) != null)
                log.info("輸出信息為 {}", lineMes);// 打印輸出信息
            try {
                // 檢查命令是否執(zhí)行失敗。
                if (p.waitFor() != 0) {
                    if (p.exitValue() == 1)// 0表示正常結(jié)束,1:非正常結(jié)束
                        log.error("命令執(zhí)行失敗");
                }
            } catch (InterruptedException e) {
                log.error("error data{}", e);
            }

        } catch (IOException e) {
            log.error("fail to carry out command{}", e);
            throw e;
        } finally {
            if (br != null) {
                br.close();
            }
        }
    }

    public static void disconnect() {
        try {
            close();
        } catch (Exception ex) {
            // Ignore because disconnection is quietly
        }
    }

    // public void execute(String command) throws Exception {
    // log.info("start execute cmd {}", command);
    // try (Session session = sshClient.startSession()) {
    // Session.Command exec = session.exec(command);
    //
    // Integer readLineCount = 0;
    // InputStream in = exec.getInputStream();
    // log.info(IOUtils.readFully(in).toString());
    // String errorMessage = IOUtils.readFully(exec.getErrorStream(), LoggerFactory.DEFAULT).toString();
    // log.info(errorMessage);
    // if (exec.getExitStatus() != null && exec.getExitStatus() != 0) {
    // throw new RuntimeException(
    // "exec " + command + " error,error message is " + errorMessage + ",error code " + exec.getExitStatus());
    // }
    // log.info("exec result code {}", exec.getExitStatus());
    //
    // }
    //
    // }
}

接下來就是調(diào)用

package com.tiduyun.cmp.operation.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.tiduyun.cmp.common.model.flow.UploadFile;
import com.tiduyun.cmp.common.model.operation.ComponentInfo;
import com.tiduyun.cmp.common.model.operation.HostInfo;
import com.tiduyun.cmp.common.provider.service.ExceptionBuildService;
import com.tiduyun.cmp.operation.constant.OperationExceptionCode;
import com.tiduyun.cmp.operation.constant.StartCmdSeparate;
import com.tiduyun.cmp.operation.model.AnsibleConfigurationItemVo;
import com.tiduyun.cmp.operation.model.vo.FileQueryVo;
import com.tiduyun.cmp.operation.service.AnsibleTaskRecordService;
import com.tiduyun.cmp.operation.service.ComposerDeployService;
import com.tiduyun.cmp.operation.service.HostInfoService;
import com.tiduyun.cmp.operation.service.UploadFileService;
import com.tiduyun.cmp.operation.utils.AnsibleExecuteTheOrderUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Service
public class AnsibleDeployServiceImpl implements ComposerDeployService {

    @Value(value = "${cmp.operation.commandHeader:cmd /c}")
    private String commandHeader;

    @Value(value = "${cmp.operation.filePath:/data/cmp/file}")
    private String filePath;

    @Value(value = "${cmp.operation.remoteFilePath:/tmp}")
    private String remoteFilePath;

    @Autowired
    private AnsibleTaskRecordService ansibleTaskRecordService;

    @Autowired
    private AnsibleConfigurationItemVo ansibleConfigurationItemVo;

    @Autowired
    private UploadFileService uploadFileService;

    @Autowired
    private HostInfoService hostInfoService;

    @Autowired
    private ExceptionBuildService exceptionBuildService;

    @Override
    public void deploy(HostInfo hostInfo, ComponentInfo componentInfo, String cpmposerName) {
        ansibleTaskRecordService.ansibleCreateHost(hostInfo, null);

        try {
            String remotePath = StringUtils.join(remoteFilePath, "/", cpmposerName, "-", componentInfo.getName(), "-",
                RandomUtil.randomString(3));
            log.info("remote file path = {}", remotePath);

            List<Integer> fileIds = getFileIds(componentInfo.getFileUrl());
            if (CollectionUtils.isNotEmpty(fileIds)) {
                FileQueryVo uploadFileQueryVo = new FileQueryVo();
                uploadFileQueryVo.setIds(fileIds);
                List<UploadFile> uploadFiles = uploadFileService.query(uploadFileQueryVo);
                for (UploadFile uploadFile : uploadFiles) {
                    String path = StringUtils.join(filePath, uploadFile.getFilePath());
                    File file = new File(path);
                    if (!file.exists()) {
                        log.error("file url is {}", file.getPath());
                        throw exceptionBuildService.buildException(OperationExceptionCode.FILE_NOT_EXIST,
                            new Object[] {uploadFile.getFileName()});
                    }
                    // 創(chuàng)建遠程目錄
                    AnsibleExecuteTheOrderUtils.createRemoteDirectory(ansibleConfigurationItemVo.getHostGroup(),
                        StringUtils.join(remotePath), ansibleConfigurationItemVo.getDirectory());

                    // 分發(fā)文件
                    AnsibleExecuteTheOrderUtils.upload(ansibleConfigurationItemVo.getHostGroup(), path,
                        StringUtils.join(remotePath, "/", uploadFile.getFileName()),
                        ansibleConfigurationItemVo.getDirectory());
                }
            }
            List<String> startCmds = getStartCmds(componentInfo.getStartCmd());
            if (CollectionUtils.isNotEmpty(startCmds)) {
                String cdCmd = StringUtils.join("cd ", remotePath);
                String execCmd = StringUtils.join(startCmds, ";");
                execCmd = StringUtils.join(cdCmd, ";", execCmd);
                log.info("execCmd= " + execCmd);
                // sshClient.execute(execCmd);
                AnsibleExecuteTheOrderUtils.ExecuteTheOrder(execCmd);

            } else {
                log.error("parse startCmd fail {}", componentInfo.getStartCmd());
            }

        } catch (Exception e) {
            log.error("主機[{}]部署[{}]組件失敗,主機ID[{}],組件ID[{}]:", hostInfo.getHost(), componentInfo.getName(),
                hostInfo.getId(), componentInfo.getId(), e);
            throw exceptionBuildService.buildException(OperationExceptionCode.EXECUTE_CMD_ERROR,
                new Object[] {e.getMessage()});

        } finally {
            AnsibleExecuteTheOrderUtils.disconnect();
        }

    }

    @Override
    public boolean isSupport(HostInfo hostInfo) {
        return true;
    }

    private List<Integer> getFileIds(String fileIds) {
        List<Integer> ids = new ArrayList<>();
        if (fileIds == null) {
            return null;
        }
        String[] split = StringUtils.split(fileIds, ",");
        for (String s : split) {
            ids.add(Integer.parseInt(s));
        }
        return ids;
    }

    private List<String> getStartCmds(String startCmd) {
        List<String> cmd = new ArrayList<>();
        if (startCmd == null) {
            return cmd;
        }
        String[] split = StrUtil.split(startCmd, StartCmdSeparate.SIGN);
        cmd.addAll(Arrays.asList(split));
        return cmd;

    }

    public static Boolean needCd(String s) {
        String[] splits = StrUtil.split(s, "&&");
        int maxIndex = splits.length - 1;
        String cmd = splits[maxIndex];
        if (StrUtil.startWith(cmd, "cd")) {
            return false;
        } else {
            return true;
        }

    }
}

文件采集

同上,調(diào)用兩個工具類

@Override
    public void fileCollection(HostInfo hostInfo, String remotePath, String localPath) {
        ansibleCreateHost(hostInfo, null);
        try {
            log.info("remote file path = {}", remotePath);
            log.info("local file path = {}", localPath);

            // 文件采集
            AnsibleExecuteTheOrderUtils.fileCollection(ansibleConfigurationItemVo.getHostGroup(), remotePath,
                localPath , ansibleConfigurationItemVo.getDirectory());
        } catch (Exception e) {
            log.error("主機[{}]文件采集失敗,主機ID[{}]:", hostInfo.getHost(), hostInfo.getId(), e);
            throw exceptionBuildService.buildException(OperationExceptionCode.EXECUTE_CMD_ERROR,
                new Object[] {e.getMessage()});

        } finally {
            AnsibleExecuteTheOrderUtils.disconnect();
        }

    }

總結(jié)

以上代碼如大家有需要,請自行更改?。?!

這些僅為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:

相關(guān)文章

  • Java面向?qū)ο蠡A(chǔ)知識之數(shù)組和鏈表

    Java面向?qū)ο蠡A(chǔ)知識之數(shù)組和鏈表

    這篇文章主要介紹了Java面向?qū)ο蟮闹當?shù)組和鏈表,文中有非常詳細的代碼示例,對正在學習java基礎(chǔ)的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-11-11
  • java基于swing實現(xiàn)的連連看代碼

    java基于swing實現(xiàn)的連連看代碼

    這篇文章主要介紹了java基于swing實現(xiàn)的連連看代碼,包含了游戲中涉及的事件處理與邏輯功能,需要的朋友可以參考下
    2014-11-11
  • 在Mybatis @Select注解中實現(xiàn)拼寫動態(tài)sql

    在Mybatis @Select注解中實現(xiàn)拼寫動態(tài)sql

    這篇文章主要介紹了在Mybatis @Select注解中實現(xiàn)拼寫動態(tài)sql,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java創(chuàng)建可執(zhí)行的Jar文件的方法實踐

    Java創(chuàng)建可執(zhí)行的Jar文件的方法實踐

    創(chuàng)建的可執(zhí)行Jar文件實際就是在原始Jar的清單文件中添加了Main-Class的配置,本文主要介紹了Java創(chuàng)建可執(zhí)行的Jar文件的方法實踐,感興趣的可以了解一下
    2023-12-12
  • IDEA main主函數(shù)如何添加args變量

    IDEA main主函數(shù)如何添加args變量

    這篇文章主要介紹了IDEA main主函數(shù)如何添加args變量,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • java 非對稱加密算法RSA實現(xiàn)詳解

    java 非對稱加密算法RSA實現(xiàn)詳解

    這篇文章主要介紹了java 非對稱加密算法RSA實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • Java數(shù)組的特性_動力節(jié)點Java學院整理

    Java數(shù)組的特性_動力節(jié)點Java學院整理

    數(shù)組是基本上所有語言都會有的一種數(shù)據(jù)類型,它表示一組相同類型的數(shù)據(jù)的集合,具有固定的長度,并且在內(nèi)存中占據(jù)連續(xù)的空間。在C,C++等語言中,數(shù)組的定義簡潔清晰,而在Java中確有一些會讓人迷惑的特性。本文就嘗試分析這些特性
    2017-04-04
  • java?面向?qū)ο蟠a塊及不同位置對屬性賦值的執(zhí)行順序

    java?面向?qū)ο蟠a塊及不同位置對屬性賦值的執(zhí)行順序

    這篇文章主要介紹了java面向?qū)ο蟠a塊及不同位置對屬性賦值的執(zhí)行順序,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • apllo開源分布式配置中心詳解

    apllo開源分布式配置中心詳解

    這篇文章主要為大家介紹了apllo開源分布式配置中心部署詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Java使用Hutool實現(xiàn)AES、DES加密解密的方法

    Java使用Hutool實現(xiàn)AES、DES加密解密的方法

    本篇文章主要介紹了Java使用Hutool實現(xiàn)AES、DES加密解密的方法,具有一定的參考價值,有興趣的可以了解一下
    2017-08-08

最新評論