通过Java代码使用Ansible操作远程Windows(完整流程)

Ansible学习笔记


学习目标:

​ 1.搭起使用环境,使用Ansible,并编写测试用例,记录问题及解决方案

​ 2.用Java操作Ansible,来访问windows,控制windows的服务与进程

具体要求:

​ 实现在远端windows执行一个脚本,或命令,把结果获取回来。

​ 例子:在远端执行一系列操作,要把目录结果获取回来。

一、Ansible远程连接windows

Ansible 从 1.7+版本开始支持Windows,但前提是管理机必须为Linux系统,远程主机的通信方式也由SSH变更为了PowerShell,同时管理机必须预安装Python的Winrm模块,才可和远程Windows主机正常通信,但PowerShell需3.0+版本且Management Framework3.0+版本

# 查看PowerShell版本
get-host

Windows Server开启winrm服务【这个服务 远程管理作用】

在PowerShell中运行

# 1.查看powershell执行策略
get-executionpolicy

# 2.更改powershell执行策略为remotesigned【输入y确认】
set-executionpolicy remotesigned

# 3.配置winrm service并启动服务
winrm quickconfig

# 4.修改winrm配置,启用远程连接认证【这里是PowerShell的命令,如果用cmd的话,@前面的' 和 末尾的' 要去掉的】
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'

# 5.查看winrm service启动监听状态【如果有应答,说明服务配置并启动成功了】
winrm enumerate winrm/config/listener

远程windows主机配置到此结束

Linux主机 Ansible 服务端配置

疑问:

不能用yum安装ansible。选择pip安装,或者二进制安装。否则,即便安装了pywinrm插件也无法管理Windows主机,yum安装的ansible无法调用pip安装的pywinrm插件!!!报错信息如下:

“msg”: “winrm or requests is not installed: No module named winrm”

检查当前CentOS系统的Python版本
# 先查看是否安装了python,如果被人更改过python命令对应的python版本,python命令可能python3,因此需要手动查看
python -V
# 检查python3是否安装
python3 -V
安装python3的依赖
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel gcc
安装Python3.8.1
 # 安装wget
yum -y install wget
 
wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
# 这里可能下载特别慢,我们可以手动下载
tar -xf Python-3.8.1.tgz 

# 配置安装路径
cd Python-3.8.1
./configure prefix=/usr/local/python3

# 编译安装python3
make && make install

# 添加软连接
ln -s /usr/local/python3/bin/python3 /usr/bin/python3
ln -s /usr/local/python3/bin/pip3.8 /usr/bin/pip3

# 检查Python3是否安装完成
python3 -v
pip3 -v
下面进行Python Winrm模块和ansible的安装
# 安装pywinrm插件
pip3 install pywinrm
# pip下载ansible(这样普通安装的话,安装可能会很慢,可以采用第三方pip源)
# pip3 install ansible 
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ansible

ln -s /usr/local/python3/bin/ansible /usr/bin/ansible
查看安装是否成功
[root@localhost ~]# ansible --version

在这里插入图片描述

下面需要对hosts文件进行配置

在这里插入图片描述

添加以下内容

在这里插入图片描述

[windows]
192.168.1.13 ansible_ssh_user="xinwei.yang" ansible_ssh_pass="123456" ansible_ssh_port=5985 ansible_connection="winrm" ansible_winrm_server_cert_valadation=ignore
测试1.然后通过win_ping 查看windows是否存活

在这里插入图片描述

测试2.win_copy 拷贝文件到远程Windows主机

在这里插入图片描述
(如果出现问题,多试几次,可能是路径或者分隔符" \ “,” / "的问题。 )
在这里插入图片描述

已经成功拷贝到远程windows机器上l

测试3 远程执行windows cmd命令!

在这里插入图片描述

[root@localhost ~]# ansible windows -m win_shell -a ‘ipconfig’

在这里插入图片描述

[root@localhost ~]# ansible windows -m win_shell -a ‘dir’

二、Java控制Windows服务与进程

我的逻辑:

在windows本机上开启Linux虚拟机(因为ansible只能安装在Linux系统上?),通过Java代码来调用服务器脚本来执行功能(Runtime.getRuntime().exec(cmd)😉,执行Ansible的功能 来实现对远端Windows服务器进行操作,最终完成对远端Windows服务进行操作(目标)

主要代码:
@Component
@Slf4j
public class AnsibleExecUtils {

    public static void exec2(String[] cmd, String path) throws IOException, InterruptedException {
        //创建File对象
        File file = new File(path);
        //执行cmd命令
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            Process p = Runtime.getRuntime().exec(cmd);
            InputStream inputStream = p.getInputStream();

            reader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));//指定字符集
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));//追加写入
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
                writer.write(line);
                //换行
                writer.newLine();
            }
            //刷新流
            writer.flush();
        } catch (IOException e) {
            //错误信息写入文件中
            writer.write(e.toString());
            e.printStackTrace();
        } finally {
            if (reader != null && writer != null) {
                reader.close();
                writer.close();
            }
        }

    }

//    private final static String filename = "hosts";
//
//    public static String getHost() {
//        String host = "192.168.1.13 ansible_ssh_user=\"xinwei.yang\" " +
//                "ansible_ssh_pass=\"123456\" " +
//                "ansible_ssh_port=5985 " +
//                "ansible_connection=\"winrm\" " +
//                "ansible_winrm_server_cert_valadation=ignore";
//        return host;
//    }
}

上面为Ansible执行的工具类

需要注意的点有:

1. reader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));//指定字符集
2. writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));//追加写入

这样就可以将我们操作的返回值写入我们自己定义的文件里

下面是我们可以执行的一些cmd命令,传递不同的参数,执行不通的操作,操作数据会保存到我们指定的文件路径

String[] cmd = {"ansible", "windows", "-m", "win_ping"}; 
String[] cmd = {"ansible", "windows", "-m", "win_shell", "-a", "ipconfig"};
String[] cmd = {"ansible", "windows", "-m", "win_copy", "-a", "src=/root/test.txt dest=D:/ansible_test/test.txt"}; //拷贝文件

Boolean aBoolean = ansibleExecService.ansibleExecuteLinux(cmd);

需要注意的是这里的"src……"字符串中,不需要多加一个单引号!!!

在这里插入图片描述

虽然命令中需要添加单引号,但是我们代码里不需要添加,加了则会出现问题!

在这里插入图片描述

通过java执行Ansible命令遇到的问题(从这篇文章受到启发)

网上有帖子写到,在java代码中执行命令操作时,需要多一些操作

//Linux系统下需要执行/bin/sh -c  xxx
private final static String commandBin = "/bin/sh";
private final static String commandC1 = "-c";

//windows系统下需要执行cmd /c xxx
private final static String commandCmd = "cmd";
private final static String commandC2 = "/c";

结果是windows的对我起了作用,反而加上Linux的却不行

下面需要在我们的Linux虚拟机中部署项目运行环境

在这里插入图片描述

安装JDK和Tomcat(如有环境可以跳过这一部分)
1.1.安装JDK

使用xftp将JDK源码包,上传到/usr/local(软件一般安装到这个目录)

1.2.解压命令进行解压
[root@localhost local]# tar -zxvf jdk-8u65-linux-x64.tar.gz
1.3.配置jdk环境变量

/etc/profile文件的改变会涉及到系统的环境,也就是有关Linux环境变量的东西

所以,我们要将jdk配置到/etc/profile,才可以在任何一个目录访问jdk

[root@localhost local]# vim /etc/profile

在profile文件末尾添加如下内容

export JAVA_HOME=/usr/local/jdk1.8.0_65  #jdk安装目录

export JRE_HOME=${JAVA_HOME}/jre 

export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
 
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
 
export PATH=$PATH:${JAVA_PATH}

保存并退出

通过命令 source /etc/profile 让profile文件立即生效

[root@localhost local]# source /etc/profile
1.4.测试是否安装成功
[root@localhost local]# javac

在这里插入图片描述

[root@localhost local]# java -version

在这里插入图片描述

2.1安装Tomcat

将上传的tomcat安装包进行解压

 tar -zxv -f apache-tomcat-8.5.37.tar.gz
 mv apache-tomcat-8.5.37 tomcat
 cd tomcat

解析完成可以启动Tomcat

/usr/local/myTomcat/tomcat/bin/startup.sh  
2.2 如果访问不了应该是防火墙的问题
- 查看防火墙状态
firewall-cmd --state
- 停止firewall
systemctl stop firewalld.service
- 禁止firewall开机启动
systemctl disable firewalld.service 
– 开放指定端口
firewall-cmd --zone=public --add-port=1935/tcp --permanent
– 关闭指定端口
firewall-cmd --zone=public --remove-port=5672/tcp --permanent
– 重启防火墙
firewall-cmd --reload

之后访问 ip地址:8080端口 便可以显示网站
在这里插入图片描述

这下便完成了基本的运行环境配置

下面需要部署我们的项目

如果是Jar包

1.查看之前启动的程序,关闭之

ps -ef|grep java
kill -9 xxx

2.启动程序

nohup java -jar XXX.jar >top.out &

如果是War包

将war包放在webapps目录下

重启Tomcat
(1)进入Tomcat的bin目录

cd /usr/local/tomcat/bin

(2)关闭Tomcat

./shutdown.sh

(3)查看Tomcat是否已关闭

ps -ef|grep java

如果显示如下相似信息,说明Tomcat还没有关闭

root      7010     1  0 Apr19 ?        00:30:13 /usr/local/java/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/tomcat/endorsed -classpath /usr/local/tomcat/bin/bootstrap.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start

使用kill命令直接杀死相应进程

kill -9 7010

(4)启动Tomcat

./startup.sh
在Linux服务器上部署SpringBoot项目并实时查看日志

如果想让项目在后台一直运行并实时打印日志,通过如下命令启动Jar:

# 先创建日志文件
touch consoleMsg.log
# 如果想让项目在后台一直运行并实时打印日志,通过如下命令启动JAR:
nohup java -jar xxx.jar > consoleMsg.log 2>&1 &
# 查看项目运行日志持续跟踪日志:
tail -f consoleMsg.log

这里我们已经将服务启动了起来

已经成功在Linux执行了命令“ping",“ipconfig”,并将命令返回值写入文件。且将文件内容copy到了远端Windows系统上

Ansible还有许多其他的模块:

**按功能分类为:**云模块、命令模块、数据库模块、文件模块、资产模块、消息模块、监控模块、网络模块、通知模块、包管理模块、源码控制模块、系统模块、单元模块、web设施模块、windows模块

在这里插入图片描述

下面我们着重会使用service模块

【官方文档】https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_service_module.html#ansible-collections-ansible-windows-win-service-module

就这样吧┭┮﹏┭┮(通过执行命令来操作)

	@ApiOperation(value = "停止远端windows的某个服务")
    @ApiImplicitParam(name = "service", value = "服务名称",paramType = "path", required = true, dataType = "String")
    @PutMapping("/stop_service/{service}")
    public Boolean stop_service(@PathVariable String service) {
        String s = "net stop " + service;
        String[] cmd = {"ansible", "windows", "-m", "win_shell", "-a", s};
        Boolean aBoolean = ansibleExecService.ansibleExecuteLinux(cmd);
        return aBoolean;
    }

    @ApiOperation("开启远端windows的某个服务")
    @ApiImplicitParam(name = "service", value = "服务名称", paramType = "path", required = true, dataType = "String")
    @PutMapping("/start_service/{service}")
    public Boolean start_service(@PathVariable String service) {
        String s = "net start " + service;
        String[] cmd = {"ansible", "windows", "-m", "win_shell", "-a", s};
        Boolean aBoolean = ansibleExecService.ansibleExecuteLinux(cmd);
        return aBoolean;
    }

这样便可以执行一些开启关闭服务的命令

结语:网络上关于java使用Ansible操作远端Windows的文章不是很多,我的代码还存在许多问题,欢迎批评指正。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值