mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 09:40:20 +00:00
Merge 3006.x into master
This commit is contained in:
commit
f60c87aacb
53 changed files with 1873 additions and 1073 deletions
1
changelog/59802.fixed.md
Normal file
1
changelog/59802.fixed.md
Normal file
|
@ -0,0 +1 @@
|
|||
Fixed merging of complex pillar overrides with salt-ssh states
|
1
changelog/60002.fixed.md
Normal file
1
changelog/60002.fixed.md
Normal file
|
@ -0,0 +1 @@
|
|||
Fixed gpg pillar rendering with salt-ssh
|
1
changelog/62230.fixed.md
Normal file
1
changelog/62230.fixed.md
Normal file
|
@ -0,0 +1 @@
|
|||
Made salt-ssh states not re-render pillars unnecessarily
|
1
changelog/65483.fixed.md
Normal file
1
changelog/65483.fixed.md
Normal file
|
@ -0,0 +1 @@
|
|||
Ensured the pillar in SSH wrapper modules is the same as the one used in template rendering when overrides are passed
|
|
@ -1 +1 @@
|
|||
centosstream-9-x86_64: ami-0df4c4ee0d3a417e6
|
||||
centosstream-9-x86_64: ami-0793e1741f291eaf9
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"almalinux-8-arm64": {
|
||||
"ami": "ami-01701198f23cc656f",
|
||||
"ami": "ami-0a2b327b74836f618",
|
||||
"ami_description": "CI Image of AlmaLinux 8 arm64",
|
||||
"ami_name": "salt-project/ci/almalinux/8/arm64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/almalinux/8/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -10,9 +10,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"almalinux-8": {
|
||||
"ami": "ami-0d1fa37788a762561",
|
||||
"ami": "ami-03d4319831692a030",
|
||||
"ami_description": "CI Image of AlmaLinux 8 x86_64",
|
||||
"ami_name": "salt-project/ci/almalinux/8/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/almalinux/8/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -20,9 +20,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"almalinux-9-arm64": {
|
||||
"ami": "ami-0690d2b725982ad83",
|
||||
"ami": "ami-01e0f60c59c6fe8f3",
|
||||
"ami_description": "CI Image of AlmaLinux 9 arm64",
|
||||
"ami_name": "salt-project/ci/almalinux/9/arm64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/almalinux/9/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -30,9 +30,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"almalinux-9": {
|
||||
"ami": "ami-0ffb222eea4b1c4ee",
|
||||
"ami": "ami-0dbbac81b50ebb8b4",
|
||||
"ami_description": "CI Image of AlmaLinux 9 x86_64",
|
||||
"ami_name": "salt-project/ci/almalinux/9/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/almalinux/9/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -40,9 +40,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"amazonlinux-2-arm64": {
|
||||
"ami": "ami-0e9521385f61055a0",
|
||||
"ami": "ami-05cc59dcbf59085f1",
|
||||
"ami_description": "CI Image of AmazonLinux 2 arm64",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2/arm64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -50,9 +50,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"amazonlinux-2": {
|
||||
"ami": "ami-038cc290cd0dd2fb3",
|
||||
"ami": "ami-07f715092c8ed2451",
|
||||
"ami_description": "CI Image of AmazonLinux 2 x86_64",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -60,9 +60,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"amazonlinux-2023-arm64": {
|
||||
"ami": "ami-00aadf98a51c60684",
|
||||
"ami": "ami-074502af4314eb812",
|
||||
"ami_description": "CI Image of AmazonLinux 2023 arm64",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2023/arm64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2023/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -70,9 +70,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"amazonlinux-2023": {
|
||||
"ami": "ami-0aeb34a1da784672c",
|
||||
"ami": "ami-0a1059334d3373321",
|
||||
"ami_description": "CI Image of AmazonLinux 2023 x86_64",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2023/x86_64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/amazonlinux/2023/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -80,9 +80,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"archlinux-lts": {
|
||||
"ami": "ami-0b4ab49118d17c567",
|
||||
"ami": "ami-0430452d2dfbb8f4b",
|
||||
"ami_description": "CI Image of ArchLinux lts x86_64",
|
||||
"ami_name": "salt-project/ci/archlinux/lts/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/archlinux/lts/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "false",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -90,9 +90,9 @@
|
|||
"ssh_username": "arch"
|
||||
},
|
||||
"centos-7-arm64": {
|
||||
"ami": "ami-0712b87973da8b106",
|
||||
"ami": "ami-0fc26a930a59d1417",
|
||||
"ami_description": "CI Image of CentOS 7 arm64",
|
||||
"ami_name": "salt-project/ci/centos/7/arm64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/centos/7/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -100,9 +100,9 @@
|
|||
"ssh_username": "centos"
|
||||
},
|
||||
"centos-7": {
|
||||
"ami": "ami-0432ac4d81ff9c6d7",
|
||||
"ami": "ami-0532c2c5f18771fa8",
|
||||
"ami_description": "CI Image of CentOS 7 x86_64",
|
||||
"ami_name": "salt-project/ci/centos/7/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/centos/7/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -110,9 +110,9 @@
|
|||
"ssh_username": "centos"
|
||||
},
|
||||
"centosstream-8-arm64": {
|
||||
"ami": "ami-00819771fc6d6f37a",
|
||||
"ami": "ami-0916df690c02e0af0",
|
||||
"ami_description": "CI Image of CentOSStream 8 arm64",
|
||||
"ami_name": "salt-project/ci/centosstream/8/arm64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/centosstream/8/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -120,9 +120,9 @@
|
|||
"ssh_username": "centos"
|
||||
},
|
||||
"centosstream-8": {
|
||||
"ami": "ami-00d0ebd1ad30509fc",
|
||||
"ami": "ami-06cf36f0232c681e2",
|
||||
"ami_description": "CI Image of CentOSStream 8 x86_64",
|
||||
"ami_name": "salt-project/ci/centosstream/8/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/centosstream/8/x86_64/20231126.1416",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -130,9 +130,9 @@
|
|||
"ssh_username": "centos"
|
||||
},
|
||||
"centosstream-9-arm64": {
|
||||
"ami": "ami-08599182d0e9788f9",
|
||||
"ami": "ami-094e17e254aa77811",
|
||||
"ami_description": "CI Image of CentOSStream 9 arm64",
|
||||
"ami_name": "salt-project/ci/centosstream/9/arm64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/centosstream/9/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -140,9 +140,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"centosstream-9": {
|
||||
"ami": "ami-0df4c4ee0d3a417e6",
|
||||
"ami": "ami-0793e1741f291eaf9",
|
||||
"ami_description": "CI Image of CentOSStream 9 x86_64",
|
||||
"ami_name": "salt-project/ci/centosstream/9/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/centosstream/9/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -150,9 +150,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"debian-10-arm64": {
|
||||
"ami": "ami-0be576b80116655d6",
|
||||
"ami": "ami-0c0b1bdab1b3c9733",
|
||||
"ami_description": "CI Image of Debian 10 arm64",
|
||||
"ami_name": "salt-project/ci/debian/10/arm64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/debian/10/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "false",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -160,9 +160,9 @@
|
|||
"ssh_username": "admin"
|
||||
},
|
||||
"debian-10": {
|
||||
"ami": "ami-0dc775a61113efde0",
|
||||
"ami": "ami-082605fda5afd9131",
|
||||
"ami_description": "CI Image of Debian 10 x86_64",
|
||||
"ami_name": "salt-project/ci/debian/10/x86_64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/debian/10/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -170,9 +170,9 @@
|
|||
"ssh_username": "admin"
|
||||
},
|
||||
"debian-11-arm64": {
|
||||
"ami": "ami-086e42800d155779f",
|
||||
"ami": "ami-0df6946d840d24ced",
|
||||
"ami_description": "CI Image of Debian 11 arm64",
|
||||
"ami_name": "salt-project/ci/debian/11/arm64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/debian/11/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "false",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -180,9 +180,9 @@
|
|||
"ssh_username": "admin"
|
||||
},
|
||||
"debian-11": {
|
||||
"ami": "ami-01b730ce9083afb7b",
|
||||
"ami": "ami-0c2198080c953861d",
|
||||
"ami_description": "CI Image of Debian 11 x86_64",
|
||||
"ami_name": "salt-project/ci/debian/11/x86_64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/debian/11/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -190,9 +190,9 @@
|
|||
"ssh_username": "admin"
|
||||
},
|
||||
"debian-12-arm64": {
|
||||
"ami": "ami-0a8fb0c54e8ac78c3",
|
||||
"ami": "ami-050b69eb0e0a66373",
|
||||
"ami_description": "CI Image of Debian 12 arm64",
|
||||
"ami_name": "salt-project/ci/debian/12/arm64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/debian/12/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "false",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -200,9 +200,9 @@
|
|||
"ssh_username": "admin"
|
||||
},
|
||||
"debian-12": {
|
||||
"ami": "ami-09736ea89f5625680",
|
||||
"ami": "ami-032e397b97865f83e",
|
||||
"ami_description": "CI Image of Debian 12 x86_64",
|
||||
"ami_name": "salt-project/ci/debian/12/x86_64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/debian/12/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -210,9 +210,9 @@
|
|||
"ssh_username": "admin"
|
||||
},
|
||||
"fedora-37-arm64": {
|
||||
"ami": "ami-067631a1bb1d3d6e4",
|
||||
"ami": "ami-0000739b5d4971ba1",
|
||||
"ami_description": "CI Image of Fedora 37 arm64",
|
||||
"ami_name": "salt-project/ci/fedora/37/arm64/20231019.0630",
|
||||
"ami_name": "salt-project/ci/fedora/37/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -220,9 +220,9 @@
|
|||
"ssh_username": "fedora"
|
||||
},
|
||||
"fedora-37": {
|
||||
"ami": "ami-03dab52e75c1d7594",
|
||||
"ami": "ami-086af8fe37696acd6",
|
||||
"ami_description": "CI Image of Fedora 37 x86_64",
|
||||
"ami_name": "salt-project/ci/fedora/37/x86_64/20231019.0630",
|
||||
"ami_name": "salt-project/ci/fedora/37/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -230,9 +230,9 @@
|
|||
"ssh_username": "fedora"
|
||||
},
|
||||
"fedora-38-arm64": {
|
||||
"ami": "ami-0a67ad5dc0b4e67a9",
|
||||
"ami": "ami-0a078cdd3a57ef342",
|
||||
"ami_description": "CI Image of Fedora 38 arm64",
|
||||
"ami_name": "salt-project/ci/fedora/38/arm64/20231019.0630",
|
||||
"ami_name": "salt-project/ci/fedora/38/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -240,9 +240,9 @@
|
|||
"ssh_username": "fedora"
|
||||
},
|
||||
"fedora-38": {
|
||||
"ami": "ami-00e8299d247d3bfb9",
|
||||
"ami": "ami-0566e7f93c5cf6afc",
|
||||
"ami_description": "CI Image of Fedora 38 x86_64",
|
||||
"ami_name": "salt-project/ci/fedora/38/x86_64/20231019.0630",
|
||||
"ami_name": "salt-project/ci/fedora/38/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -250,9 +250,9 @@
|
|||
"ssh_username": "fedora"
|
||||
},
|
||||
"opensuse-15": {
|
||||
"ami": "ami-0fa4ce121739032e2",
|
||||
"ami": "ami-0c64c574d488d33f6",
|
||||
"ami_description": "CI Image of Opensuse 15 x86_64",
|
||||
"ami_name": "salt-project/ci/opensuse/15/x86_64/20231019.0611",
|
||||
"ami_name": "salt-project/ci/opensuse/15/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -260,9 +260,9 @@
|
|||
"ssh_username": "ec2-user"
|
||||
},
|
||||
"photonos-3-arm64": {
|
||||
"ami": "ami-09687bbdca9322cfd",
|
||||
"ami": "ami-03ac724168ce02eed",
|
||||
"ami_description": "CI Image of PhotonOS 3 arm64",
|
||||
"ami_name": "salt-project/ci/photonos/3/arm64/20231019.0626",
|
||||
"ami_name": "salt-project/ci/photonos/3/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -270,9 +270,9 @@
|
|||
"ssh_username": "root"
|
||||
},
|
||||
"photonos-3": {
|
||||
"ami": "ami-0e29021a535519231",
|
||||
"ami": "ami-0072dfd1f7bc5f586",
|
||||
"ami_description": "CI Image of PhotonOS 3 x86_64",
|
||||
"ami_name": "salt-project/ci/photonos/3/x86_64/20231019.0626",
|
||||
"ami_name": "salt-project/ci/photonos/3/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -280,9 +280,9 @@
|
|||
"ssh_username": "root"
|
||||
},
|
||||
"photonos-4-arm64": {
|
||||
"ami": "ami-06a0418b67a9ec332",
|
||||
"ami": "ami-05a215fe4cf29227b",
|
||||
"ami_description": "CI Image of PhotonOS 4 arm64",
|
||||
"ami_name": "salt-project/ci/photonos/4/arm64/20231019.0626",
|
||||
"ami_name": "salt-project/ci/photonos/4/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -290,9 +290,9 @@
|
|||
"ssh_username": "root"
|
||||
},
|
||||
"photonos-4": {
|
||||
"ami": "ami-08ae023a2755a60dc",
|
||||
"ami": "ami-06addda42fc8c5db3",
|
||||
"ami_description": "CI Image of PhotonOS 4 x86_64",
|
||||
"ami_name": "salt-project/ci/photonos/4/x86_64/20231019.0626",
|
||||
"ami_name": "salt-project/ci/photonos/4/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -300,9 +300,9 @@
|
|||
"ssh_username": "root"
|
||||
},
|
||||
"photonos-5-arm64": {
|
||||
"ami": "ami-05b3dd82b94e82736",
|
||||
"ami": "ami-0e78012df225dbe96",
|
||||
"ami_description": "CI Image of PhotonOS 5 arm64",
|
||||
"ami_name": "salt-project/ci/photonos/5/arm64/20231019.0627",
|
||||
"ami_name": "salt-project/ci/photonos/5/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -310,9 +310,9 @@
|
|||
"ssh_username": "root"
|
||||
},
|
||||
"photonos-5": {
|
||||
"ami": "ami-016991d4c267732c3",
|
||||
"ami": "ami-0fc61f964bc262714",
|
||||
"ami_description": "CI Image of PhotonOS 5 x86_64",
|
||||
"ami_name": "salt-project/ci/photonos/5/x86_64/20231019.0627",
|
||||
"ami_name": "salt-project/ci/photonos/5/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -320,9 +320,9 @@
|
|||
"ssh_username": "root"
|
||||
},
|
||||
"ubuntu-20.04-arm64": {
|
||||
"ami": "ami-0dc851d4db96c052b",
|
||||
"ami": "ami-0cc504307b587cd77",
|
||||
"ami_description": "CI Image of Ubuntu 20.04 arm64",
|
||||
"ami_name": "salt-project/ci/ubuntu/20.04/arm64/20231019.0628",
|
||||
"ami_name": "salt-project/ci/ubuntu/20.04/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -330,9 +330,9 @@
|
|||
"ssh_username": "ubuntu"
|
||||
},
|
||||
"ubuntu-20.04": {
|
||||
"ami": "ami-05c262fca2254d2cb",
|
||||
"ami": "ami-03376fca39f6d9186",
|
||||
"ami_description": "CI Image of Ubuntu 20.04 x86_64",
|
||||
"ami_name": "salt-project/ci/ubuntu/20.04/x86_64/20231019.0627",
|
||||
"ami_name": "salt-project/ci/ubuntu/20.04/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -340,9 +340,9 @@
|
|||
"ssh_username": "ubuntu"
|
||||
},
|
||||
"ubuntu-22.04-arm64": {
|
||||
"ami": "ami-007415ef606318020",
|
||||
"ami": "ami-0be361d529bb46410",
|
||||
"ami_description": "CI Image of Ubuntu 22.04 arm64",
|
||||
"ami_name": "salt-project/ci/ubuntu/22.04/arm64/20231019.0628",
|
||||
"ami_name": "salt-project/ci/ubuntu/22.04/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -350,9 +350,9 @@
|
|||
"ssh_username": "ubuntu"
|
||||
},
|
||||
"ubuntu-22.04": {
|
||||
"ami": "ami-04d01b95ca8570ed3",
|
||||
"ami": "ami-0c9d29f29868da4ce",
|
||||
"ami_description": "CI Image of Ubuntu 22.04 x86_64",
|
||||
"ami_name": "salt-project/ci/ubuntu/22.04/x86_64/20231019.0628",
|
||||
"ami_name": "salt-project/ci/ubuntu/22.04/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -360,9 +360,9 @@
|
|||
"ssh_username": "ubuntu"
|
||||
},
|
||||
"ubuntu-23.04-arm64": {
|
||||
"ami": "ami-0da01b22cca0f4281",
|
||||
"ami": "ami-0b80ab7ead3c7d289",
|
||||
"ami_description": "CI Image of Ubuntu 23.04 arm64",
|
||||
"ami_name": "salt-project/ci/ubuntu/23.04/arm64/20231019.0629",
|
||||
"ami_name": "salt-project/ci/ubuntu/23.04/arm64/20231126.1417",
|
||||
"arch": "arm64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "m6g.large",
|
||||
|
@ -370,9 +370,9 @@
|
|||
"ssh_username": "ubuntu"
|
||||
},
|
||||
"ubuntu-23.04": {
|
||||
"ami": "ami-03e32d8e9ccc6cd6a",
|
||||
"ami": "ami-0d17dce1842e37811",
|
||||
"ami_description": "CI Image of Ubuntu 23.04 x86_64",
|
||||
"ami_name": "salt-project/ci/ubuntu/23.04/x86_64/20231019.0629",
|
||||
"ami_name": "salt-project/ci/ubuntu/23.04/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.large",
|
||||
|
@ -380,9 +380,9 @@
|
|||
"ssh_username": "ubuntu"
|
||||
},
|
||||
"windows-2016": {
|
||||
"ami": "ami-02fd868528f2c7a62",
|
||||
"ami": "ami-043db64b3b46a804c",
|
||||
"ami_description": "CI Image of Windows 2016 x86_64",
|
||||
"ami_name": "salt-project/ci/windows/2016/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/windows/2016/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.xlarge",
|
||||
|
@ -390,9 +390,9 @@
|
|||
"ssh_username": "Administrator"
|
||||
},
|
||||
"windows-2019": {
|
||||
"ami": "ami-0d6f2b5a109c98224",
|
||||
"ami": "ami-0f7a8dc8862bff13f",
|
||||
"ami_description": "CI Image of Windows 2019 x86_64",
|
||||
"ami_name": "salt-project/ci/windows/2019/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/windows/2019/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.xlarge",
|
||||
|
@ -400,9 +400,9 @@
|
|||
"ssh_username": "Administrator"
|
||||
},
|
||||
"windows-2022": {
|
||||
"ami": "ami-013e3141df4b2418f",
|
||||
"ami": "ami-05a829f3649aa33d6",
|
||||
"ami_description": "CI Image of Windows 2022 x86_64",
|
||||
"ami_name": "salt-project/ci/windows/2022/x86_64/20231019.0610",
|
||||
"ami_name": "salt-project/ci/windows/2022/x86_64/20231126.1417",
|
||||
"arch": "x86_64",
|
||||
"cloudwatch-agent-available": "true",
|
||||
"instance_type": "t3a.xlarge",
|
||||
|
|
|
@ -10,3 +10,4 @@ pytest-httpserver
|
|||
pytest-custom-exit-code >= 0.3
|
||||
flaky
|
||||
more-itertools
|
||||
pyfakefs
|
||||
|
|
|
@ -40,7 +40,7 @@ pycparser==2.21
|
|||
# via
|
||||
# -c requirements/static/ci/py3.10/linux.txt
|
||||
# cffi
|
||||
pypsexec==0.3.0
|
||||
pypsexec==0.1.0
|
||||
# via -r requirements/static/ci/cloud.in
|
||||
pyspnego==0.9.0
|
||||
# via
|
||||
|
@ -62,6 +62,7 @@ six==1.16.0
|
|||
# via
|
||||
# -c requirements/static/ci/py3.10/linux.txt
|
||||
# profitbricks
|
||||
# pypsexec
|
||||
# pywinrm
|
||||
smbprotocol==1.10.1
|
||||
# via
|
||||
|
|
|
@ -320,6 +320,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/darwin.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -324,6 +324,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pyinotify==0.9.6 ; sys_platform != "win32" and sys_platform != "darwin" and platform_system != "openbsd"
|
||||
# via -r requirements/static/ci/common.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -351,6 +351,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/linux.in
|
||||
pyiface==0.0.11
|
||||
|
|
|
@ -275,6 +275,8 @@ pydantic==1.10.8
|
|||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.10/windows.txt
|
||||
# inflect
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/windows.in
|
||||
pymssql==2.2.7 ; sys_platform == "win32"
|
||||
|
|
|
@ -34,8 +34,6 @@ netaddr==0.8.0
|
|||
# via
|
||||
# -c requirements/static/ci/py3.11/linux.txt
|
||||
# -r requirements/static/ci/cloud.in
|
||||
ntlm-auth==1.3.0
|
||||
# via requests-ntlm
|
||||
profitbricks==4.1.3
|
||||
# via -r requirements/static/ci/cloud.in
|
||||
pycparser==2.21
|
||||
|
@ -44,13 +42,14 @@ pycparser==2.21
|
|||
# cffi
|
||||
pypsexec==0.1.0
|
||||
# via -r requirements/static/ci/cloud.in
|
||||
pyspnego==0.8.0
|
||||
pyspnego==0.9.0
|
||||
# via
|
||||
# -r requirements/static/ci/cloud.in
|
||||
# requests-ntlm
|
||||
# smbprotocol
|
||||
pywinrm==0.3.0
|
||||
pywinrm==0.4.3
|
||||
# via -r requirements/static/ci/cloud.in
|
||||
requests-ntlm==1.1.0
|
||||
requests-ntlm==1.2.0
|
||||
# via pywinrm
|
||||
requests==2.31.0
|
||||
# via
|
||||
|
|
|
@ -324,6 +324,8 @@ pydantic==2.5.2
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/darwin.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -328,6 +328,8 @@ pydantic==2.5.2
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pyinotify==0.9.6 ; sys_platform != "win32" and sys_platform != "darwin" and platform_system != "openbsd"
|
||||
# via -r requirements/static/ci/common.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -353,6 +353,8 @@ pydantic==2.5.2
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/linux.in
|
||||
pyiface==0.0.11
|
||||
|
|
|
@ -94,6 +94,7 @@ cryptography==41.0.5
|
|||
# etcd3-py
|
||||
# moto
|
||||
# pyopenssl
|
||||
# pyspnego
|
||||
# requests-ntlm
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
|
@ -229,8 +230,6 @@ multidict==6.0.2
|
|||
# via
|
||||
# aiohttp
|
||||
# yarl
|
||||
ntlm-auth==1.5.0
|
||||
# via requests-ntlm
|
||||
packaging==23.1
|
||||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.11/windows.txt
|
||||
|
@ -280,6 +279,8 @@ pydantic==2.5.2
|
|||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.11/windows.txt
|
||||
# inflect
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/windows.in
|
||||
pymssql==2.2.7 ; sys_platform == "win32"
|
||||
|
@ -299,6 +300,8 @@ pyopenssl==23.2.0
|
|||
# etcd3-py
|
||||
pyrsistent==0.19.3
|
||||
# via jsonschema
|
||||
pyspnego==0.10.2
|
||||
# via requests-ntlm
|
||||
pytest-custom-exit-code==0.3.0
|
||||
# via -r requirements/pytest.txt
|
||||
pytest-helpers-namespace==2021.12.29
|
||||
|
@ -364,7 +367,7 @@ pywin32==305 ; sys_platform == "win32"
|
|||
# docker
|
||||
# pytest-skip-markers
|
||||
# wmi
|
||||
pywinrm==0.4.1
|
||||
pywinrm==0.4.3
|
||||
# via -r requirements/static/ci/windows.in
|
||||
pyyaml==6.0.1
|
||||
# via
|
||||
|
@ -380,7 +383,7 @@ pyzmq==25.1.1
|
|||
# -c requirements/static/ci/../pkg/py3.11/windows.txt
|
||||
# -r requirements/zeromq.txt
|
||||
# pytest-salt-factories
|
||||
requests-ntlm==1.1.0
|
||||
requests-ntlm==1.2.0
|
||||
# via pywinrm
|
||||
requests==2.31.0
|
||||
# via
|
||||
|
@ -429,6 +432,8 @@ smmap==5.0.0
|
|||
# via gitdb
|
||||
sqlparse==0.4.4
|
||||
# via -r requirements/static/ci/common.in
|
||||
sspilib==0.1.0
|
||||
# via pyspnego
|
||||
strict-rfc3339==0.7
|
||||
# via -r requirements/static/ci/common.in
|
||||
tempora==5.3.0
|
||||
|
|
|
@ -381,8 +381,6 @@ ntc-templates==4.0.1
|
|||
# via
|
||||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
# netmiko
|
||||
ntlm-auth==1.3.0
|
||||
# via requests-ntlm
|
||||
oscrypto==1.3.0
|
||||
# via
|
||||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
|
@ -463,6 +461,10 @@ pyeapi==1.0.0
|
|||
# via
|
||||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
# napalm
|
||||
pyfakefs==5.3.1
|
||||
# via
|
||||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
# -r requirements/pytest.txt
|
||||
pyinotify==0.9.6 ; sys_platform != "win32" and sys_platform != "darwin" and platform_system != "openbsd"
|
||||
# via
|
||||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
|
@ -493,9 +495,10 @@ pyserial==3.5
|
|||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
# junos-eznc
|
||||
# netmiko
|
||||
pyspnego==0.8.0
|
||||
pyspnego==0.9.0
|
||||
# via
|
||||
# -r requirements/static/ci/cloud.in
|
||||
# requests-ntlm
|
||||
# smbprotocol
|
||||
pytest-custom-exit-code==0.3.0
|
||||
# via
|
||||
|
@ -577,7 +580,7 @@ pyvmomi==8.0.1.0.1
|
|||
# via
|
||||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
# -r requirements/static/ci/common.in
|
||||
pywinrm==0.3.0
|
||||
pywinrm==0.4.3
|
||||
# via -r requirements/static/ci/cloud.in
|
||||
pyyaml==6.0.1
|
||||
# via
|
||||
|
@ -598,7 +601,7 @@ pyzmq==25.1.1
|
|||
# -c requirements/static/ci/py3.12/linux.txt
|
||||
# -r requirements/zeromq.txt
|
||||
# pytest-salt-factories
|
||||
requests-ntlm==1.1.0
|
||||
requests-ntlm==1.2.0
|
||||
# via pywinrm
|
||||
requests==2.31.0
|
||||
# via
|
||||
|
|
|
@ -324,6 +324,8 @@ pydantic==2.5.2
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/darwin.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -328,6 +328,8 @@ pydantic==2.5.2
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pyinotify==0.9.6 ; sys_platform != "win32" and sys_platform != "darwin" and platform_system != "openbsd"
|
||||
# via -r requirements/static/ci/common.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -353,6 +353,8 @@ pydantic==2.5.2
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/linux.in
|
||||
pyiface==0.0.11
|
||||
|
|
|
@ -273,6 +273,7 @@ pycryptodomex==3.10.1
|
|||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.11/windows.txt
|
||||
# -r requirements/crypto.txt
|
||||
|
||||
pydantic-core==2.14.5
|
||||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.11/windows.txt
|
||||
|
@ -281,6 +282,11 @@ pydantic==2.5.2
|
|||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.11/windows.txt
|
||||
# inflect
|
||||
|
||||
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/windows.in
|
||||
pymssql==2.2.7 ; sys_platform == "win32"
|
||||
|
@ -366,7 +372,7 @@ pywin32==306 ; sys_platform == "win32"
|
|||
# docker
|
||||
# pytest-skip-markers
|
||||
# wmi
|
||||
pywinrm==0.4.1
|
||||
pywinrm==0.4.3
|
||||
# via -r requirements/static/ci/windows.in
|
||||
pyyaml==6.0.1
|
||||
# via
|
||||
|
@ -381,7 +387,7 @@ pyzmq==25.1.1
|
|||
# -c requirements/static/ci/../pkg/py3.11/windows.txt
|
||||
# -r requirements/zeromq.txt
|
||||
# pytest-salt-factories
|
||||
requests-ntlm==1.1.0
|
||||
requests-ntlm==1.2.0
|
||||
# via pywinrm
|
||||
requests==2.31.0
|
||||
# via
|
||||
|
|
|
@ -40,7 +40,7 @@ pycparser==2.21
|
|||
# via
|
||||
# -c requirements/static/ci/py3.8/linux.txt
|
||||
# cffi
|
||||
pypsexec==0.3.0
|
||||
pypsexec==0.1.0
|
||||
# via -r requirements/static/ci/cloud.in
|
||||
pyspnego==0.9.0
|
||||
# via
|
||||
|
@ -62,6 +62,7 @@ six==1.16.0
|
|||
# via
|
||||
# -c requirements/static/ci/py3.8/linux.txt
|
||||
# profitbricks
|
||||
# pypsexec
|
||||
# pywinrm
|
||||
smbprotocol==1.10.1
|
||||
# via
|
||||
|
|
|
@ -328,6 +328,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pyinotify==0.9.6 ; sys_platform != "win32" and sys_platform != "darwin" and platform_system != "openbsd"
|
||||
# via -r requirements/static/ci/common.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -355,6 +355,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/linux.in
|
||||
pyiface==0.0.11
|
||||
|
|
|
@ -279,6 +279,8 @@ pydantic==1.10.8
|
|||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.8/windows.txt
|
||||
# inflect
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/windows.in
|
||||
pymssql==2.2.7 ; sys_platform == "win32"
|
||||
|
|
|
@ -40,7 +40,7 @@ pycparser==2.21
|
|||
# via
|
||||
# -c requirements/static/ci/py3.9/linux.txt
|
||||
# cffi
|
||||
pypsexec==0.3.0
|
||||
pypsexec==0.1.0
|
||||
# via -r requirements/static/ci/cloud.in
|
||||
pyspnego==0.9.0
|
||||
# via
|
||||
|
@ -62,6 +62,7 @@ six==1.16.0
|
|||
# via
|
||||
# -c requirements/static/ci/py3.9/linux.txt
|
||||
# profitbricks
|
||||
# pypsexec
|
||||
# pywinrm
|
||||
smbprotocol==1.10.1
|
||||
# via
|
||||
|
|
|
@ -320,6 +320,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/darwin.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -324,6 +324,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pyinotify==0.9.6 ; sys_platform != "win32" and sys_platform != "darwin" and platform_system != "openbsd"
|
||||
# via -r requirements/static/ci/common.in
|
||||
pynacl==1.5.0
|
||||
|
|
|
@ -353,6 +353,8 @@ pydantic==1.10.8
|
|||
# inflect
|
||||
pyeapi==1.0.0
|
||||
# via napalm
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/linux.in
|
||||
pyiface==0.0.11
|
||||
|
|
|
@ -275,6 +275,8 @@ pydantic==1.10.8
|
|||
# via
|
||||
# -c requirements/static/ci/../pkg/py3.9/windows.txt
|
||||
# inflect
|
||||
pyfakefs==5.3.1
|
||||
# via -r requirements/pytest.txt
|
||||
pygit2==1.13.1
|
||||
# via -r requirements/static/ci/windows.in
|
||||
pymssql==2.2.7 ; sys_platform == "win32"
|
||||
|
|
|
@ -93,6 +93,17 @@ warnings.filterwarnings(
|
|||
category=DeprecationWarning,
|
||||
)
|
||||
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
"Deprecated call to `pkg_resources.declare_namespace.*",
|
||||
category=DeprecationWarning,
|
||||
)
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
".*pkg_resources is deprecated as an API.*",
|
||||
category=DeprecationWarning,
|
||||
)
|
||||
|
||||
|
||||
def __define_global_system_encoding_variable__():
|
||||
# This is the most trustworthy source of the system encoding, though, if
|
||||
|
|
|
@ -1196,9 +1196,11 @@ class Single:
|
|||
for grain in self.target["grains"]:
|
||||
opts_pkg["grains"][grain] = self.target["grains"][grain]
|
||||
|
||||
# Pillar compilation needs the master opts primarily,
|
||||
# same as during regular operation.
|
||||
popts = {}
|
||||
popts.update(opts_pkg["__master_opts__"])
|
||||
popts.update(opts_pkg)
|
||||
popts.update(opts_pkg["__master_opts__"])
|
||||
pillar = salt.pillar.Pillar(
|
||||
popts,
|
||||
opts_pkg["grains"],
|
||||
|
|
|
@ -31,10 +31,17 @@ class SSHState(salt.state.State):
|
|||
Create a State object which wraps the SSH functions for state operations
|
||||
"""
|
||||
|
||||
def __init__(self, opts, pillar=None, wrapper=None, context=None):
|
||||
def __init__(
|
||||
self,
|
||||
opts,
|
||||
pillar_override=None,
|
||||
wrapper=None,
|
||||
context=None,
|
||||
initial_pillar=None,
|
||||
):
|
||||
self.wrapper = wrapper
|
||||
self.context = context
|
||||
super().__init__(opts, pillar)
|
||||
super().__init__(opts, pillar_override, initial_pillar=initial_pillar)
|
||||
|
||||
def load_modules(self, data=None, proxy=None):
|
||||
"""
|
||||
|
@ -49,6 +56,28 @@ class SSHState(salt.state.State):
|
|||
)
|
||||
self.rend = salt.loader.render(self.opts, self.functions)
|
||||
|
||||
def _gather_pillar(self):
|
||||
"""
|
||||
The opts used during pillar rendering should contain the master
|
||||
opts in the root namespace. self.opts is the modified minion opts,
|
||||
containing the original master opts in __master_opts__.
|
||||
"""
|
||||
_opts = self.opts
|
||||
popts = {}
|
||||
# Pillar compilation needs the master opts primarily,
|
||||
# same as during regular operation.
|
||||
popts.update(_opts)
|
||||
popts.update(_opts.get("__master_opts__", {}))
|
||||
# But, salt.state.State takes the parameters for get_pillar from
|
||||
# the opts, so we need to ensure they are correct for the minion.
|
||||
popts["id"] = _opts["id"]
|
||||
popts["saltenv"] = _opts["saltenv"]
|
||||
popts["pillarenv"] = _opts.get("pillarenv")
|
||||
self.opts = popts
|
||||
pillar = super()._gather_pillar()
|
||||
self.opts = _opts
|
||||
return pillar
|
||||
|
||||
def check_refresh(self, data, ret):
|
||||
"""
|
||||
Stub out check_refresh
|
||||
|
@ -69,10 +98,24 @@ class SSHHighState(salt.state.BaseHighState):
|
|||
|
||||
stack = []
|
||||
|
||||
def __init__(self, opts, pillar=None, wrapper=None, fsclient=None, context=None):
|
||||
def __init__(
|
||||
self,
|
||||
opts,
|
||||
pillar_override=None,
|
||||
wrapper=None,
|
||||
fsclient=None,
|
||||
context=None,
|
||||
initial_pillar=None,
|
||||
):
|
||||
self.client = fsclient
|
||||
salt.state.BaseHighState.__init__(self, opts)
|
||||
self.state = SSHState(opts, pillar, wrapper, context=context)
|
||||
self.state = SSHState(
|
||||
opts,
|
||||
pillar_override,
|
||||
wrapper,
|
||||
context=context,
|
||||
initial_pillar=initial_pillar,
|
||||
)
|
||||
self.matchers = salt.loader.matchers(self.opts)
|
||||
|
||||
self._pydsl_all_decls = {}
|
||||
|
|
|
@ -28,7 +28,7 @@ __func_alias__ = {"apply_": "apply"}
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _ssh_state(chunks, st_kwargs, kwargs, test=False):
|
||||
def _ssh_state(chunks, st_kwargs, kwargs, pillar, test=False):
|
||||
"""
|
||||
Function to run a state with the given chunk via salt-ssh
|
||||
"""
|
||||
|
@ -43,7 +43,7 @@ def _ssh_state(chunks, st_kwargs, kwargs, test=False):
|
|||
__context__["fileclient"],
|
||||
chunks,
|
||||
file_refs,
|
||||
__pillar__.value(),
|
||||
pillar,
|
||||
st_kwargs["id_"],
|
||||
)
|
||||
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__["hash_type"])
|
||||
|
@ -173,21 +173,30 @@ def sls(mods, saltenv="base", test=None, exclude=None, **kwargs):
|
|||
"""
|
||||
st_kwargs = __salt__.kwargs
|
||||
__opts__["grains"] = __grains__.value()
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
opts["test"] = _get_test_value(test, **kwargs)
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
pillar_override = kwargs.get("pillar")
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__.value(),
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
__context__["retcode"] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
|
||||
err = ["Pillar failed to render with the following messages:"]
|
||||
err += st_.opts["pillar"]["_errors"]
|
||||
return err
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
st_.push_active()
|
||||
mods = _parse_mods(mods)
|
||||
high_data, errors = st_.render_highstate(
|
||||
|
@ -231,7 +240,7 @@ def sls(mods, saltenv="base", test=None, exclude=None, **kwargs):
|
|||
__context__["fileclient"],
|
||||
chunks,
|
||||
file_refs,
|
||||
__pillar__.value(),
|
||||
pillar,
|
||||
st_kwargs["id_"],
|
||||
roster_grains,
|
||||
)
|
||||
|
@ -329,12 +338,7 @@ def _check_queue(queue, kwargs):
|
|||
|
||||
|
||||
def _get_initial_pillar(opts):
|
||||
return (
|
||||
__pillar__
|
||||
if __opts__["__cli"] == "salt-call"
|
||||
and opts["pillarenv"] == __opts__["pillarenv"]
|
||||
else None
|
||||
)
|
||||
return __pillar__.value() if opts["pillarenv"] == __opts__["pillarenv"] else None
|
||||
|
||||
|
||||
def low(data, **kwargs):
|
||||
|
@ -353,10 +357,11 @@ def low(data, **kwargs):
|
|||
chunks = [data]
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
__opts__,
|
||||
__pillar__.value(),
|
||||
None,
|
||||
__salt__.value(),
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=__pillar__.value(),
|
||||
) as st_:
|
||||
for chunk in chunks:
|
||||
chunk["__id__"] = (
|
||||
|
@ -440,17 +445,26 @@ def high(data, **kwargs):
|
|||
|
||||
salt '*' state.high '{"vim": {"pkg": ["installed"]}}'
|
||||
"""
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
st_kwargs = __salt__.kwargs
|
||||
__opts__["grains"] = __grains__.value()
|
||||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
pillar_override = kwargs.get("pillar")
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__.value(),
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
st_.push_active()
|
||||
chunks = st_.state.compile_high_data(data)
|
||||
file_refs = salt.client.ssh.state.lowstate_file_refs(
|
||||
|
@ -469,7 +483,7 @@ def high(data, **kwargs):
|
|||
__context__["fileclient"],
|
||||
chunks,
|
||||
file_refs,
|
||||
__pillar__.value(),
|
||||
pillar,
|
||||
st_kwargs["id_"],
|
||||
roster_grains,
|
||||
)
|
||||
|
@ -677,23 +691,32 @@ def highstate(test=None, **kwargs):
|
|||
salt '*' state.highstate exclude=sls_to_exclude
|
||||
salt '*' state.highstate exclude="[{'id': 'id_to_exclude'}, {'sls': 'sls_to_exclude'}]"
|
||||
"""
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
st_kwargs = __salt__.kwargs
|
||||
__opts__["grains"] = __grains__.value()
|
||||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
opts["test"] = _get_test_value(test, **kwargs)
|
||||
pillar_override = kwargs.get("pillar")
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__.value(),
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
__context__["retcode"] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
|
||||
err = ["Pillar failed to render with the following messages:"]
|
||||
err += st_.opts["pillar"]["_errors"]
|
||||
return err
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
st_.push_active()
|
||||
chunks = st_.compile_low_chunks(context=__context__.value())
|
||||
file_refs = salt.client.ssh.state.lowstate_file_refs(
|
||||
|
@ -717,7 +740,7 @@ def highstate(test=None, **kwargs):
|
|||
__context__["fileclient"],
|
||||
chunks,
|
||||
file_refs,
|
||||
__pillar__.value(),
|
||||
pillar,
|
||||
st_kwargs["id_"],
|
||||
roster_grains,
|
||||
)
|
||||
|
@ -764,26 +787,32 @@ def top(topfn, test=None, **kwargs):
|
|||
salt '*' state.top reverse_top.sls exclude=sls_to_exclude
|
||||
salt '*' state.top reverse_top.sls exclude="[{'id': 'id_to_exclude'}, {'sls': 'sls_to_exclude'}]"
|
||||
"""
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
st_kwargs = __salt__.kwargs
|
||||
__opts__["grains"] = __grains__.value()
|
||||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
opts["test"] = True
|
||||
else:
|
||||
opts["test"] = __opts__.get("test", None)
|
||||
opts["test"] = _get_test_value(test, **kwargs)
|
||||
pillar_override = kwargs.get("pillar")
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__.value(),
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
__context__["retcode"] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
|
||||
err = ["Pillar failed to render with the following messages:"]
|
||||
err += st_.opts["pillar"]["_errors"]
|
||||
return err
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
st_.opts["state_top"] = os.path.join("salt://", topfn)
|
||||
st_.push_active()
|
||||
chunks = st_.compile_low_chunks(context=__context__.value())
|
||||
|
@ -808,7 +837,7 @@ def top(topfn, test=None, **kwargs):
|
|||
__context__["fileclient"],
|
||||
chunks,
|
||||
file_refs,
|
||||
__pillar__.value(),
|
||||
pillar,
|
||||
st_kwargs["id_"],
|
||||
roster_grains,
|
||||
)
|
||||
|
@ -855,18 +884,28 @@ def show_highstate(**kwargs):
|
|||
"""
|
||||
__opts__["grains"] = __grains__.value()
|
||||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
pillar_override = kwargs.get("pillar")
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__,
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
__context__["retcode"] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
|
||||
err = ["Pillar failed to render with the following messages:"]
|
||||
err += st_.opts["pillar"]["_errors"]
|
||||
return err
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
st_.push_active()
|
||||
chunks = st_.compile_highstate(context=__context__.value())
|
||||
# Check for errors
|
||||
|
@ -891,10 +930,11 @@ def show_lowstate(**kwargs):
|
|||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
None,
|
||||
__salt__,
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=_get_initial_pillar(opts),
|
||||
) as st_:
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
__context__["retcode"] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
|
||||
|
@ -939,7 +979,6 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
|
||||
salt '*' state.sls_id my_state my_module,a_common_module
|
||||
"""
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
st_kwargs = __salt__.kwargs
|
||||
conflict = _check_queue(queue, kwargs)
|
||||
if conflict is not None:
|
||||
|
@ -953,12 +992,15 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
if opts["saltenv"] is None:
|
||||
opts["saltenv"] = "base"
|
||||
|
||||
pillar_override = kwargs.get("pillar")
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
__opts__,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__,
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
|
@ -967,6 +1009,13 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
err += __pillar__["_errors"]
|
||||
return err
|
||||
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
split_mods = _parse_mods(mods)
|
||||
st_.push_active()
|
||||
high_, errors = st_.render_highstate(
|
||||
|
@ -992,7 +1041,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|||
)
|
||||
)
|
||||
|
||||
ret = _ssh_state(chunk, st_kwargs, kwargs, test=test)
|
||||
ret = _ssh_state(chunk, st_kwargs, kwargs, pillar, test=test)
|
||||
_set_retcode(ret, highstate=highstate)
|
||||
# Work around Windows multiprocessing bug, set __opts__['test'] back to
|
||||
# value from before this function was run.
|
||||
|
@ -1011,25 +1060,31 @@ def show_sls(mods, saltenv="base", test=None, **kwargs):
|
|||
|
||||
salt '*' state.show_sls core,edit.vim dev
|
||||
"""
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
__opts__["grains"] = __grains__.value()
|
||||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
opts["test"] = True
|
||||
else:
|
||||
opts["test"] = __opts__.get("test", None)
|
||||
opts["test"] = _get_test_value(test, **kwargs)
|
||||
pillar_override = kwargs.get("pillar")
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__,
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
__context__["retcode"] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
|
||||
err = ["Pillar failed to render with the following messages:"]
|
||||
err += st_.opts["pillar"]["_errors"]
|
||||
return err
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
st_.push_active()
|
||||
mods = _parse_mods(mods)
|
||||
high_data, errors = st_.render_highstate(
|
||||
|
@ -1065,26 +1120,31 @@ def show_low_sls(mods, saltenv="base", test=None, **kwargs):
|
|||
|
||||
salt '*' state.show_low_sls core,edit.vim dev
|
||||
"""
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
__opts__["grains"] = __grains__.value()
|
||||
|
||||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
opts["test"] = True
|
||||
else:
|
||||
opts["test"] = __opts__.get("test", None)
|
||||
opts["test"] = _get_test_value(test, **kwargs)
|
||||
pillar_override = kwargs.get("pillar")
|
||||
initial_pillar = _get_initial_pillar(opts)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
pillar_override,
|
||||
__salt__,
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=initial_pillar,
|
||||
) as st_:
|
||||
if not _check_pillar(kwargs, st_.opts["pillar"]):
|
||||
__context__["retcode"] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
|
||||
err = ["Pillar failed to render with the following messages:"]
|
||||
err += st_.opts["pillar"]["_errors"]
|
||||
return err
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
if pillar_override is not None or initial_pillar is None:
|
||||
# Ensure other wrappers use the correct pillar
|
||||
__pillar__.update(pillar)
|
||||
st_.push_active()
|
||||
mods = _parse_mods(mods)
|
||||
high_data, errors = st_.render_highstate(
|
||||
|
@ -1122,10 +1182,11 @@ def show_top(**kwargs):
|
|||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
with salt.client.ssh.state.SSHHighState(
|
||||
opts,
|
||||
__pillar__.value(),
|
||||
None,
|
||||
__salt__,
|
||||
__context__["fileclient"],
|
||||
context=__context__.value(),
|
||||
initial_pillar=_get_initial_pillar(opts),
|
||||
) as st_:
|
||||
top_data = st_.get_top(context=__context__.value())
|
||||
errors = []
|
||||
|
@ -1171,17 +1232,22 @@ def single(fun, name, test=None, **kwargs):
|
|||
opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
|
||||
|
||||
# Set test mode
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
opts["test"] = True
|
||||
else:
|
||||
opts["test"] = __opts__.get("test", None)
|
||||
opts["test"] = _get_test_value(test, **kwargs)
|
||||
|
||||
# Get the override pillar data
|
||||
__pillar__.update(kwargs.get("pillar", {}))
|
||||
# This needs to be removed from the kwargs, they are called
|
||||
# as a lowstate with one item, not a single chunk
|
||||
pillar_override = kwargs.pop("pillar", None)
|
||||
|
||||
# Create the State environment
|
||||
st_ = salt.client.ssh.state.SSHState(opts, __pillar__)
|
||||
st_ = salt.client.ssh.state.SSHState(
|
||||
opts, pillar_override, initial_pillar=_get_initial_pillar(opts)
|
||||
)
|
||||
|
||||
try:
|
||||
pillar = st_.opts["pillar"].value()
|
||||
except AttributeError:
|
||||
pillar = st_.opts["pillar"]
|
||||
# Verify the low chunk
|
||||
err = st_.verify_data(kwargs)
|
||||
if err:
|
||||
|
@ -1208,7 +1274,7 @@ def single(fun, name, test=None, **kwargs):
|
|||
__context__["fileclient"],
|
||||
chunks,
|
||||
file_refs,
|
||||
__pillar__.value(),
|
||||
pillar,
|
||||
st_kwargs["id_"],
|
||||
roster_grains,
|
||||
)
|
||||
|
|
|
@ -10,6 +10,7 @@ System module for sleeping, restarting, and shutting down the system on Mac OS X
|
|||
import getpass
|
||||
import shlex
|
||||
|
||||
import salt.utils.mac_utils
|
||||
import salt.utils.platform
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
|
||||
|
@ -71,7 +72,7 @@ def _execute_command(cmd, at_time=None):
|
|||
Returns: bool
|
||||
"""
|
||||
if at_time:
|
||||
cmd = "echo '{}' | at {}".format(cmd, shlex.quote(at_time))
|
||||
cmd = f"echo '{cmd}' | at {shlex.quote(at_time)}"
|
||||
return not bool(__salt__["cmd.retcode"](cmd, python_shell=True))
|
||||
|
||||
|
||||
|
@ -204,10 +205,10 @@ def get_remote_login():
|
|||
|
||||
salt '*' system.get_remote_login
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"]("systemsetup -getremotelogin")
|
||||
ret = salt.utils.mac_utils.execute_return_result("systemsetup -getremotelogin")
|
||||
|
||||
enabled = __utils__["mac_utils.validate_enabled"](
|
||||
__utils__["mac_utils.parse_return"](ret)
|
||||
enabled = salt.utils.mac_utils.validate_enabled(
|
||||
salt.utils.mac_utils.parse_return(ret)
|
||||
)
|
||||
|
||||
return enabled == "on"
|
||||
|
@ -230,12 +231,12 @@ def set_remote_login(enable):
|
|||
|
||||
salt '*' system.set_remote_login True
|
||||
"""
|
||||
state = __utils__["mac_utils.validate_enabled"](enable)
|
||||
state = salt.utils.mac_utils.validate_enabled(enable)
|
||||
|
||||
cmd = "systemsetup -f -setremotelogin {}".format(state)
|
||||
__utils__["mac_utils.execute_return_success"](cmd)
|
||||
cmd = f"systemsetup -f -setremotelogin {state}"
|
||||
salt.utils.mac_utils.execute_return_success(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
state, get_remote_login, normalize_ret=True
|
||||
)
|
||||
|
||||
|
@ -253,12 +254,12 @@ def get_remote_events():
|
|||
|
||||
salt '*' system.get_remote_events
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"](
|
||||
ret = salt.utils.mac_utils.execute_return_result(
|
||||
"systemsetup -getremoteappleevents"
|
||||
)
|
||||
|
||||
enabled = __utils__["mac_utils.validate_enabled"](
|
||||
__utils__["mac_utils.parse_return"](ret)
|
||||
enabled = salt.utils.mac_utils.validate_enabled(
|
||||
salt.utils.mac_utils.parse_return(ret)
|
||||
)
|
||||
|
||||
return enabled == "on"
|
||||
|
@ -282,12 +283,12 @@ def set_remote_events(enable):
|
|||
|
||||
salt '*' system.set_remote_events On
|
||||
"""
|
||||
state = __utils__["mac_utils.validate_enabled"](enable)
|
||||
state = salt.utils.mac_utils.validate_enabled(enable)
|
||||
|
||||
cmd = "systemsetup -setremoteappleevents {}".format(state)
|
||||
__utils__["mac_utils.execute_return_success"](cmd)
|
||||
cmd = f"systemsetup -setremoteappleevents {state}"
|
||||
salt.utils.mac_utils.execute_return_success(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
state,
|
||||
get_remote_events,
|
||||
normalize_ret=True,
|
||||
|
@ -307,9 +308,9 @@ def get_computer_name():
|
|||
|
||||
salt '*' system.get_computer_name
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"]("scutil --get ComputerName")
|
||||
ret = salt.utils.mac_utils.execute_return_result("scutil --get ComputerName")
|
||||
|
||||
return __utils__["mac_utils.parse_return"](ret)
|
||||
return salt.utils.mac_utils.parse_return(ret)
|
||||
|
||||
|
||||
def set_computer_name(name):
|
||||
|
@ -327,10 +328,10 @@ def set_computer_name(name):
|
|||
|
||||
salt '*' system.set_computer_name "Mike's Mac"
|
||||
"""
|
||||
cmd = 'scutil --set ComputerName "{}"'.format(name)
|
||||
__utils__["mac_utils.execute_return_success"](cmd)
|
||||
cmd = f'scutil --set ComputerName "{name}"'
|
||||
salt.utils.mac_utils.execute_return_success(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
name,
|
||||
get_computer_name,
|
||||
)
|
||||
|
@ -349,11 +350,9 @@ def get_subnet_name():
|
|||
|
||||
salt '*' system.get_subnet_name
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"](
|
||||
"systemsetup -getlocalsubnetname"
|
||||
)
|
||||
ret = salt.utils.mac_utils.execute_return_result("systemsetup -getlocalsubnetname")
|
||||
|
||||
return __utils__["mac_utils.parse_return"](ret)
|
||||
return salt.utils.mac_utils.parse_return(ret)
|
||||
|
||||
|
||||
def set_subnet_name(name):
|
||||
|
@ -375,10 +374,10 @@ def set_subnet_name(name):
|
|||
The following will be set as 'Mikes-Mac'
|
||||
salt '*' system.set_subnet_name "Mike's Mac"
|
||||
"""
|
||||
cmd = 'systemsetup -setlocalsubnetname "{}"'.format(name)
|
||||
__utils__["mac_utils.execute_return_success"](cmd)
|
||||
cmd = f'systemsetup -setlocalsubnetname "{name}"'
|
||||
salt.utils.mac_utils.execute_return_success(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
name,
|
||||
get_subnet_name,
|
||||
)
|
||||
|
@ -397,9 +396,9 @@ def get_startup_disk():
|
|||
|
||||
salt '*' system.get_startup_disk
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"]("systemsetup -getstartupdisk")
|
||||
ret = salt.utils.mac_utils.execute_return_result("systemsetup -getstartupdisk")
|
||||
|
||||
return __utils__["mac_utils.parse_return"](ret)
|
||||
return salt.utils.mac_utils.parse_return(ret)
|
||||
|
||||
|
||||
def list_startup_disks():
|
||||
|
@ -415,7 +414,7 @@ def list_startup_disks():
|
|||
|
||||
salt '*' system.list_startup_disks
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"]("systemsetup -liststartupdisks")
|
||||
ret = salt.utils.mac_utils.execute_return_result("systemsetup -liststartupdisks")
|
||||
|
||||
return ret.splitlines()
|
||||
|
||||
|
@ -445,10 +444,10 @@ def set_startup_disk(path):
|
|||
)
|
||||
raise SaltInvocationError(msg)
|
||||
|
||||
cmd = "systemsetup -setstartupdisk {}".format(path)
|
||||
__utils__["mac_utils.execute_return_result"](cmd)
|
||||
cmd = f"systemsetup -setstartupdisk {path}"
|
||||
salt.utils.mac_utils.execute_return_result(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
path,
|
||||
get_startup_disk,
|
||||
)
|
||||
|
@ -469,11 +468,11 @@ def get_restart_delay():
|
|||
|
||||
salt '*' system.get_restart_delay
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"](
|
||||
ret = salt.utils.mac_utils.execute_return_result(
|
||||
"systemsetup -getwaitforstartupafterpowerfailure"
|
||||
)
|
||||
|
||||
return __utils__["mac_utils.parse_return"](ret)
|
||||
return salt.utils.mac_utils.parse_return(ret)
|
||||
|
||||
|
||||
def set_restart_delay(seconds):
|
||||
|
@ -512,10 +511,10 @@ def set_restart_delay(seconds):
|
|||
)
|
||||
raise SaltInvocationError(msg)
|
||||
|
||||
cmd = "systemsetup -setwaitforstartupafterpowerfailure {}".format(seconds)
|
||||
__utils__["mac_utils.execute_return_success"](cmd)
|
||||
cmd = f"systemsetup -setwaitforstartupafterpowerfailure {seconds}"
|
||||
salt.utils.mac_utils.execute_return_success(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
seconds,
|
||||
get_restart_delay,
|
||||
)
|
||||
|
@ -535,12 +534,12 @@ def get_disable_keyboard_on_lock():
|
|||
|
||||
salt '*' system.get_disable_keyboard_on_lock
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"](
|
||||
ret = salt.utils.mac_utils.execute_return_result(
|
||||
"systemsetup -getdisablekeyboardwhenenclosurelockisengaged"
|
||||
)
|
||||
|
||||
enabled = __utils__["mac_utils.validate_enabled"](
|
||||
__utils__["mac_utils.parse_return"](ret)
|
||||
enabled = salt.utils.mac_utils.validate_enabled(
|
||||
salt.utils.mac_utils.parse_return(ret)
|
||||
)
|
||||
|
||||
return enabled == "on"
|
||||
|
@ -564,12 +563,12 @@ def set_disable_keyboard_on_lock(enable):
|
|||
|
||||
salt '*' system.set_disable_keyboard_on_lock False
|
||||
"""
|
||||
state = __utils__["mac_utils.validate_enabled"](enable)
|
||||
state = salt.utils.mac_utils.validate_enabled(enable)
|
||||
|
||||
cmd = "systemsetup -setdisablekeyboardwhenenclosurelockisengaged {}".format(state)
|
||||
__utils__["mac_utils.execute_return_success"](cmd)
|
||||
cmd = f"systemsetup -setdisablekeyboardwhenenclosurelockisengaged {state}"
|
||||
salt.utils.mac_utils.execute_return_success(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
state,
|
||||
get_disable_keyboard_on_lock,
|
||||
normalize_ret=True,
|
||||
|
@ -589,11 +588,11 @@ def get_boot_arch():
|
|||
|
||||
salt '*' system.get_boot_arch
|
||||
"""
|
||||
ret = __utils__["mac_utils.execute_return_result"](
|
||||
ret = salt.utils.mac_utils.execute_return_result(
|
||||
"systemsetup -getkernelbootarchitecturesetting"
|
||||
)
|
||||
|
||||
arch = __utils__["mac_utils.parse_return"](ret)
|
||||
arch = salt.utils.mac_utils.parse_return(ret)
|
||||
|
||||
if "default" in arch:
|
||||
return "default"
|
||||
|
@ -639,10 +638,10 @@ def set_boot_arch(arch="default"):
|
|||
)
|
||||
raise SaltInvocationError(msg)
|
||||
|
||||
cmd = "systemsetup -setkernelbootarchitecture {}".format(arch)
|
||||
__utils__["mac_utils.execute_return_success"](cmd)
|
||||
cmd = f"systemsetup -setkernelbootarchitecture {arch}"
|
||||
salt.utils.mac_utils.execute_return_success(cmd)
|
||||
|
||||
return __utils__["mac_utils.confirm_updated"](
|
||||
return salt.utils.mac_utils.confirm_updated(
|
||||
arch,
|
||||
get_boot_arch,
|
||||
)
|
||||
|
|
|
@ -1,263 +0,0 @@
|
|||
"""
|
||||
integration tests for mac_system
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
from saltfactories.utils import random_string
|
||||
|
||||
from tests.support.case import ModuleCase
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
SET_COMPUTER_NAME = random_string("RS-", lowercase=False)
|
||||
SET_SUBNET_NAME = random_string("RS-", lowercase=False)
|
||||
|
||||
|
||||
@pytest.mark.flaky(max_runs=10)
|
||||
@pytest.mark.skip_unless_on_darwin
|
||||
@pytest.mark.usefixtures("salt_sub_minion")
|
||||
@pytest.mark.skip_if_not_root
|
||||
@pytest.mark.skip_if_binaries_missing("systemsetup")
|
||||
@pytest.mark.slow_test
|
||||
class MacSystemModuleTest(ModuleCase):
|
||||
"""
|
||||
Validate the mac_system module
|
||||
"""
|
||||
|
||||
ATRUN_ENABLED = False
|
||||
REMOTE_LOGIN_ENABLED = False
|
||||
REMOTE_EVENTS_ENABLED = False
|
||||
SUBNET_NAME = ""
|
||||
KEYBOARD_DISABLED = False
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Get current settings
|
||||
"""
|
||||
self.ATRUN_ENABLED = self.run_function("service.enabled", ["com.apple.atrun"])
|
||||
self.REMOTE_LOGIN_ENABLED = self.run_function("system.get_remote_login")
|
||||
self.REMOTE_EVENTS_ENABLED = self.run_function("system.get_remote_events")
|
||||
self.SUBNET_NAME = self.run_function("system.get_subnet_name")
|
||||
self.KEYBOARD_DISABLED = self.run_function(
|
||||
"system.get_disable_keyboard_on_lock"
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Reset to original settings
|
||||
"""
|
||||
if not self.ATRUN_ENABLED:
|
||||
atrun = "/System/Library/LaunchDaemons/com.apple.atrun.plist"
|
||||
self.run_function("service.stop", [atrun])
|
||||
|
||||
self.run_function("system.set_remote_login", [self.REMOTE_LOGIN_ENABLED])
|
||||
self.run_function("system.set_remote_events", [self.REMOTE_EVENTS_ENABLED])
|
||||
self.run_function("system.set_subnet_name", [self.SUBNET_NAME])
|
||||
self.run_function(
|
||||
"system.set_disable_keyboard_on_lock", [self.KEYBOARD_DISABLED]
|
||||
)
|
||||
|
||||
@pytest.mark.destructive_test
|
||||
@pytest.mark.slow_test
|
||||
def test_get_set_remote_login(self):
|
||||
"""
|
||||
Test system.get_remote_login
|
||||
Test system.set_remote_login
|
||||
"""
|
||||
# Normal Functionality
|
||||
self.assertTrue(self.run_function("system.set_remote_login", [True]))
|
||||
self.assertTrue(self.run_function("system.get_remote_login"))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", [False]))
|
||||
self.assertFalse(self.run_function("system.get_remote_login"))
|
||||
|
||||
# Test valid input
|
||||
self.assertTrue(self.run_function("system.set_remote_login", [True]))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", [False]))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", ["yes"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", ["no"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", ["On"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", ["Off"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", [1]))
|
||||
self.assertTrue(self.run_function("system.set_remote_login", [0]))
|
||||
|
||||
# Test invalid input
|
||||
self.assertIn(
|
||||
"Invalid String Value for Enabled",
|
||||
self.run_function("system.set_remote_login", ["spongebob"]),
|
||||
)
|
||||
|
||||
@pytest.mark.destructive_test
|
||||
@pytest.mark.slow_test
|
||||
def test_get_set_remote_events(self):
|
||||
"""
|
||||
Test system.get_remote_events
|
||||
Test system.set_remote_events
|
||||
"""
|
||||
# Normal Functionality
|
||||
self.assertTrue(self.run_function("system.set_remote_events", [True]))
|
||||
self.assertTrue(self.run_function("system.get_remote_events"))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", [False]))
|
||||
self.assertFalse(self.run_function("system.get_remote_events"))
|
||||
|
||||
# Test valid input
|
||||
self.assertTrue(self.run_function("system.set_remote_events", [True]))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", [False]))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", ["yes"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", ["no"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", ["On"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", ["Off"]))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", [1]))
|
||||
self.assertTrue(self.run_function("system.set_remote_events", [0]))
|
||||
|
||||
# Test invalid input
|
||||
self.assertIn(
|
||||
"Invalid String Value for Enabled",
|
||||
self.run_function("system.set_remote_events", ["spongebob"]),
|
||||
)
|
||||
|
||||
@pytest.mark.destructive_test
|
||||
@pytest.mark.slow_test
|
||||
def test_get_set_subnet_name(self):
|
||||
"""
|
||||
Test system.get_subnet_name
|
||||
Test system.set_subnet_name
|
||||
"""
|
||||
self.assertTrue(self.run_function("system.set_subnet_name", [SET_SUBNET_NAME]))
|
||||
self.assertEqual(self.run_function("system.get_subnet_name"), SET_SUBNET_NAME)
|
||||
|
||||
@pytest.mark.slow_test
|
||||
@pytest.mark.skip_initial_gh_actions_failure
|
||||
def test_get_list_startup_disk(self):
|
||||
"""
|
||||
Test system.get_startup_disk
|
||||
Test system.list_startup_disks
|
||||
Don't know how to test system.set_startup_disk as there's usually only
|
||||
one startup disk available on a system
|
||||
"""
|
||||
# Test list and get
|
||||
ret = self.run_function("system.list_startup_disks")
|
||||
self.assertIsInstance(ret, list)
|
||||
self.assertIn(self.run_function("system.get_startup_disk"), ret)
|
||||
|
||||
# Test passing set a bad disk
|
||||
self.assertIn(
|
||||
"Invalid value passed for path.",
|
||||
self.run_function("system.set_startup_disk", ["spongebob"]),
|
||||
)
|
||||
|
||||
@pytest.mark.skip(reason="Skip this test until mac fixes it.")
|
||||
def test_get_set_restart_delay(self):
|
||||
"""
|
||||
Test system.get_restart_delay
|
||||
Test system.set_restart_delay
|
||||
system.set_restart_delay does not work due to an apple bug, see docs
|
||||
may need to disable this test as we can't control the delay value
|
||||
"""
|
||||
# Normal Functionality
|
||||
self.assertTrue(self.run_function("system.set_restart_delay", [90]))
|
||||
self.assertEqual(self.run_function("system.get_restart_delay"), "90 seconds")
|
||||
|
||||
# Pass set bad value for seconds
|
||||
self.assertIn(
|
||||
"Invalid value passed for seconds.",
|
||||
self.run_function("system.set_restart_delay", [70]),
|
||||
)
|
||||
|
||||
@pytest.mark.slow_test
|
||||
def test_get_set_disable_keyboard_on_lock(self):
|
||||
"""
|
||||
Test system.get_disable_keyboard_on_lock
|
||||
Test system.set_disable_keyboard_on_lock
|
||||
"""
|
||||
# Normal Functionality
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", [True])
|
||||
)
|
||||
self.assertTrue(self.run_function("system.get_disable_keyboard_on_lock"))
|
||||
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", [False])
|
||||
)
|
||||
self.assertFalse(self.run_function("system.get_disable_keyboard_on_lock"))
|
||||
|
||||
# Test valid input
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", [True])
|
||||
)
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", [False])
|
||||
)
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", ["yes"])
|
||||
)
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", ["no"])
|
||||
)
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", ["On"])
|
||||
)
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_disable_keyboard_on_lock", ["Off"])
|
||||
)
|
||||
self.assertTrue(self.run_function("system.set_disable_keyboard_on_lock", [1]))
|
||||
self.assertTrue(self.run_function("system.set_disable_keyboard_on_lock", [0]))
|
||||
|
||||
# Test invalid input
|
||||
self.assertIn(
|
||||
"Invalid String Value for Enabled",
|
||||
self.run_function("system.set_disable_keyboard_on_lock", ["spongebob"]),
|
||||
)
|
||||
|
||||
@pytest.mark.skip(reason="Skip this test until mac fixes it.")
|
||||
def test_get_set_boot_arch(self):
|
||||
"""
|
||||
Test system.get_boot_arch
|
||||
Test system.set_boot_arch
|
||||
system.set_boot_arch does not work due to an apple bug, see docs
|
||||
may need to disable this test as we can't set the boot architecture
|
||||
"""
|
||||
# Normal Functionality
|
||||
self.assertTrue(self.run_function("system.set_boot_arch", ["i386"]))
|
||||
self.assertEqual(self.run_function("system.get_boot_arch"), "i386")
|
||||
self.assertTrue(self.run_function("system.set_boot_arch", ["default"]))
|
||||
self.assertEqual(self.run_function("system.get_boot_arch"), "default")
|
||||
|
||||
# Test invalid input
|
||||
self.assertIn(
|
||||
"Invalid value passed for arch",
|
||||
self.run_function("system.set_boot_arch", ["spongebob"]),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_unless_on_darwin
|
||||
@pytest.mark.skip_if_not_root
|
||||
class MacSystemComputerNameTest(ModuleCase):
|
||||
def setUp(self):
|
||||
self.COMPUTER_NAME = self.run_function("system.get_computer_name")
|
||||
self.wait_for_all_jobs()
|
||||
|
||||
def tearDown(self):
|
||||
self.run_function("system.set_computer_name", [self.COMPUTER_NAME])
|
||||
self.wait_for_all_jobs()
|
||||
|
||||
# A similar test used to be skipped on py3 due to 'hanging', if we see
|
||||
# something similar again we may want to skip this gain until we
|
||||
# investigate
|
||||
# @pytest.mark.skipif(salt.utils.platform.is_darwin() and six.PY3, reason='This test hangs on OS X on Py3. Skipping until #53566 is merged.')
|
||||
@pytest.mark.destructive_test
|
||||
@pytest.mark.slow_test
|
||||
def test_get_set_computer_name(self):
|
||||
"""
|
||||
Test system.get_computer_name
|
||||
Test system.set_computer_name
|
||||
"""
|
||||
log.debug("Set name is %s", SET_COMPUTER_NAME)
|
||||
self.assertTrue(
|
||||
self.run_function("system.set_computer_name", [SET_COMPUTER_NAME])
|
||||
)
|
||||
self.assertEqual(
|
||||
self.run_function("system.get_computer_name"), SET_COMPUTER_NAME
|
||||
)
|
356
tests/pytests/functional/modules/test_mac_system.py
Normal file
356
tests/pytests/functional/modules/test_mac_system.py
Normal file
|
@ -0,0 +1,356 @@
|
|||
"""
|
||||
integration tests for mac_system
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
from saltfactories.utils import random_string
|
||||
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.slow_test,
|
||||
pytest.mark.skip_if_not_root,
|
||||
pytest.mark.skip_unless_on_darwin,
|
||||
pytest.mark.skip_if_binaries_missing("systemsetup"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def service(modules):
|
||||
return modules.service
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def system(modules):
|
||||
return modules.system
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _remote_login_cleanup(system, grains):
|
||||
if grains["osmajorrelease"] >= 13:
|
||||
pytest.skip("SKipping until we figure out how to have full dist access")
|
||||
|
||||
remote_login_enabled = system.get_remote_login()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if system.get_remote_login() != remote_login_enabled:
|
||||
system.set_remote_login(remote_login_enabled)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _remote_events_cleanup(system, grains):
|
||||
if grains["osmajorrelease"] >= 13:
|
||||
pytest.skip("SKipping until we figure out how to have full dist access")
|
||||
|
||||
remote_events_enabled = system.get_remote_events()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if system.get_remote_events() != remote_events_enabled:
|
||||
system.set_remote_events(remote_events_enabled)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _subnet_cleanup(system):
|
||||
subnet_name = system.get_subnet_name()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if system.get_subnet_name() != subnet_name:
|
||||
system.set_subnet_name(subnet_name)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _keyboard_cleanup(system):
|
||||
keyboard_disabled = system.get_disable_keyboard_on_lock()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if system.get_disable_keyboard_on_lock() != keyboard_disabled:
|
||||
system.set_disable_keyboard_on_lock(keyboard_disabled)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _computer_name_cleanup(system):
|
||||
computer_name = system.get_computer_name()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if system.get_computer_name() != computer_name:
|
||||
system.set_computer_name(computer_name)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _setup_teardown_vars(service, system):
|
||||
atrun_enabled = service.enabled("com.apple.atrun")
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if not atrun_enabled:
|
||||
atrun = "/System/Library/LaunchDaemons/com.apple.atrun.plist"
|
||||
service.stop(atrun)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("_remote_login_cleanup")
|
||||
def test_get_set_remote_login(system):
|
||||
"""
|
||||
Test system.get_remote_login
|
||||
Test system.set_remote_login
|
||||
"""
|
||||
# Normal Functionality
|
||||
ret = system.set_remote_login(True)
|
||||
assert ret
|
||||
|
||||
ret = system.get_remote_login()
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login(False)
|
||||
assert ret
|
||||
|
||||
ret = system.get_remote_login()
|
||||
assert not ret
|
||||
|
||||
# Test valid input
|
||||
ret = system.set_remote_login(True)
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login(False)
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login("yes")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login("no")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login("On")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login("Off")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login(1)
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_login(0)
|
||||
assert ret
|
||||
|
||||
# Test invalid input
|
||||
with pytest.raises(SaltInvocationError) as exc:
|
||||
system.set_remote_login("spongebob")
|
||||
assert "Invalid String Value for Enabled" in str(exc.value)
|
||||
|
||||
|
||||
@pytest.mark.skip_initial_gh_actions_failure
|
||||
@pytest.mark.usefixtures("_remote_events_cleanup")
|
||||
def test_get_set_remote_events(system):
|
||||
"""
|
||||
Test system.get_remote_events
|
||||
Test system.set_remote_events
|
||||
"""
|
||||
# Normal Functionality
|
||||
ret = system.set_remote_events(True)
|
||||
assert ret
|
||||
|
||||
ret = system.get_remote_events()
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events(False)
|
||||
assert ret
|
||||
|
||||
ret = not system.get_remote_events()
|
||||
assert not ret
|
||||
|
||||
# Test valid input
|
||||
ret = system.set_remote_events(True)
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events(False)
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events("yes")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events("no")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events("On")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events("Off")
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events(1)
|
||||
assert ret
|
||||
|
||||
ret = system.set_remote_events(0)
|
||||
assert ret
|
||||
|
||||
# Test invalid input
|
||||
with pytest.raises(CommandExecutionError) as exc:
|
||||
system.set_remote_events("spongebob")
|
||||
assert "Invalid String Value for Enabled" in str(exc.value)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("_subnet_cleanup")
|
||||
def test_get_set_subnet_name(system):
|
||||
"""
|
||||
Test system.get_subnet_name
|
||||
Test system.set_subnet_name
|
||||
"""
|
||||
set_subnet_name = random_string("RS-", lowercase=False)
|
||||
|
||||
ret = system.set_subnet_name(set_subnet_name)
|
||||
assert ret
|
||||
|
||||
ret = system.get_subnet_name()
|
||||
assert ret == set_subnet_name
|
||||
|
||||
|
||||
@pytest.mark.skip_initial_gh_actions_failure
|
||||
def test_get_list_startup_disk(system):
|
||||
"""
|
||||
Test system.get_startup_disk
|
||||
Test system.list_startup_disks
|
||||
Don't know how to test system.set_startup_disk as there's usually only
|
||||
one startup disk available on a system
|
||||
"""
|
||||
# Test list and get
|
||||
ret = system.list_startup_disks()
|
||||
assert isinstance(ret, list)
|
||||
|
||||
startup_disk = system.get_startup_disk()
|
||||
assert startup_disk in ret
|
||||
|
||||
# Test passing set a bad disk
|
||||
with pytest.raises(SaltInvocationError) as exc:
|
||||
system.set_startup_disk("spongebob")
|
||||
assert "Invalid value passed for path." in str(exc.value)
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Skip this test until mac fixes it.")
|
||||
def test_get_set_restart_delay(system):
|
||||
"""
|
||||
Test system.get_restart_delay
|
||||
Test system.set_restart_delay
|
||||
system.set_restart_delay does not work due to an apple bug, see docs
|
||||
may need to disable this test as we can't control the delay value
|
||||
"""
|
||||
# Normal Functionality
|
||||
ret = system.set_restart_delay(90)
|
||||
assert ret
|
||||
|
||||
ret = system.get_restart_delay()
|
||||
assert ret == "90 seconds"
|
||||
|
||||
# Pass set bad value for seconds
|
||||
with pytest.raises(CommandExecutionError) as exc:
|
||||
system.set_restart_delay(70)
|
||||
assert "Invalid value passed for seconds." in str(exc.value)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("_keyboard_cleanup")
|
||||
def test_get_set_disable_keyboard_on_lock(system):
|
||||
"""
|
||||
Test system.get_disable_keyboard_on_lock
|
||||
Test system.set_disable_keyboard_on_lock
|
||||
"""
|
||||
# Normal Functionality
|
||||
ret = system.set_disable_keyboard_on_lock(True)
|
||||
assert ret
|
||||
|
||||
ret = system.get_disable_keyboard_on_lock()
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock(False)
|
||||
assert ret
|
||||
|
||||
ret = system.get_disable_keyboard_on_lock()
|
||||
assert not ret
|
||||
|
||||
# Test valid input
|
||||
ret = system.set_disable_keyboard_on_lock(True)
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock(False)
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock("yes")
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock("no")
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock("On")
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock("Off")
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock(1)
|
||||
assert ret
|
||||
|
||||
ret = system.set_disable_keyboard_on_lock(0)
|
||||
assert ret
|
||||
|
||||
# Test invalid input
|
||||
with pytest.raises(SaltInvocationError) as exc:
|
||||
system.set_disable_keyboard_on_lock("spongebob")
|
||||
assert "Invalid String Value for Enabled" in str(exc.value)
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Skip this test until mac fixes it.")
|
||||
def test_get_set_boot_arch(system):
|
||||
"""
|
||||
Test system.get_boot_arch
|
||||
Test system.set_boot_arch
|
||||
system.set_boot_arch does not work due to an apple bug, see docs
|
||||
may need to disable this test as we can't set the boot architecture
|
||||
"""
|
||||
# Normal Functionality
|
||||
ret = system.set_boot_arch("i386")
|
||||
assert ret
|
||||
|
||||
ret = system.get_boot_arch()
|
||||
assert ret == "i386"
|
||||
|
||||
ret = system.set_boot_arch("default")
|
||||
assert ret
|
||||
|
||||
ret = system.get_boot_arch()
|
||||
assert ret == "default"
|
||||
|
||||
# Test invalid input
|
||||
with pytest.raises(CommandExecutionError) as exc:
|
||||
system.set_boot_arch("spongebob")
|
||||
assert "Invalid value passed for arch" in str(exc.value)
|
||||
|
||||
|
||||
# A similar test used to be skipped on py3 due to 'hanging', if we see
|
||||
# something similar again we may want to skip this gain until we
|
||||
# investigate
|
||||
# @pytest.mark.skipif(salt.utils.platform.is_darwin() and six.PY3, reason='This test hangs on OS X on Py3. Skipping until #53566 is merged.')
|
||||
@pytest.mark.destructive_test
|
||||
@pytest.mark.usefixtures("_computer_name_cleanup")
|
||||
def test_get_set_computer_name(system):
|
||||
"""
|
||||
Test system.get_computer_name
|
||||
Test system.set_computer_name
|
||||
"""
|
||||
set_computer_name = random_string("RS-", lowercase=False)
|
||||
|
||||
computer_name = system.get_computer_name()
|
||||
|
||||
log.debug("set name is %s", set_computer_name)
|
||||
ret = system.set_computer_name(set_computer_name)
|
||||
assert ret
|
||||
|
||||
ret = system.get_computer_name()
|
||||
assert ret == set_computer_name
|
||||
|
||||
system.set_computer_name(computer_name)
|
|
@ -70,7 +70,22 @@ def PKG_CAP_TARGETS(grains):
|
|||
_PKG_CAP_TARGETS = []
|
||||
if grains["os_family"] == "Suse":
|
||||
if grains["os"] == "SUSE":
|
||||
_PKG_CAP_TARGETS = [("perl(ZNC)", "znc-perl")]
|
||||
_PKG_CAP_TARGETS = [("perl(YAML)", "perl-YAML")]
|
||||
# sudo zypper install 'perl(YAML)'
|
||||
# Loading repository data...
|
||||
# Reading installed packages...
|
||||
# 'perl(YAML)' not found in package names. Trying capabilities.
|
||||
# Resolving package dependencies...
|
||||
#
|
||||
# The following NEW package is going to be installed:
|
||||
# perl-YAML
|
||||
#
|
||||
# 1 new package to install.
|
||||
# Overall download size: 85.3 KiB. Already cached: 0 B. After the operation, additional 183.3 KiB will be used.
|
||||
# Continue? [y/n/v/...? shows all options] (y):
|
||||
|
||||
# So, it just doesn't work here? skip it for now
|
||||
_PKG_CAP_TARGETS.clear()
|
||||
if not _PKG_CAP_TARGETS:
|
||||
pytest.skip("Capability not provided")
|
||||
return _PKG_CAP_TARGETS
|
||||
|
|
|
@ -417,11 +417,13 @@ class TestVirtMigrateTest:
|
|||
assert domains == []
|
||||
|
||||
def test_ssh_migration(
|
||||
self, salt_cli, virt_minion_0, virt_minion_1, prep_virt, virt_domain
|
||||
self, salt_cli, virt_minion_0, virt_minion_1, prep_virt, virt_domain, grains
|
||||
):
|
||||
"""
|
||||
Test domain migration over SSH, TCP and TLS transport protocol
|
||||
"""
|
||||
if grains["os"] == "VMware Photon OS" and grains["osmajorrelease"] == 3:
|
||||
pytest.skip("Skipping this test on PhotonOS 3")
|
||||
ret = salt_cli.run("virt.list_active_vms", minion_tgt=virt_minion_0.id)
|
||||
assert ret.returncode == 0, ret
|
||||
|
||||
|
|
132
tests/pytests/integration/ssh/state/conftest.py
Normal file
132
tests/pytests/integration/ssh/state/conftest.py
Normal file
|
@ -0,0 +1,132 @@
|
|||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def state_tree(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
{%- from "map.jinja" import abc with context %}
|
||||
base:
|
||||
'localhost':
|
||||
- basic
|
||||
'127.0.0.1':
|
||||
- basic
|
||||
"""
|
||||
map_file = """
|
||||
{%- set abc = "def" %}
|
||||
"""
|
||||
state_file = """
|
||||
{%- from "map.jinja" import abc with context %}
|
||||
Ok with {{ abc }}:
|
||||
test.succeed_without_changes
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
map_tempfile = pytest.helpers.temp_file(
|
||||
"map.jinja", map_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"test.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, map_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def state_tree_dir(base_env_state_tree_root_dir):
|
||||
"""
|
||||
State tree with files to test salt-ssh
|
||||
when the map.jinja file is in another directory
|
||||
"""
|
||||
top_file = """
|
||||
{%- from "test/map.jinja" import abc with context %}
|
||||
base:
|
||||
'localhost':
|
||||
- test
|
||||
'127.0.0.1':
|
||||
- test
|
||||
"""
|
||||
map_file = """
|
||||
{%- set abc = "def" %}
|
||||
"""
|
||||
state_file = """
|
||||
{%- from "test/map.jinja" import abc with context %}
|
||||
|
||||
Ok with {{ abc }}:
|
||||
test.succeed_without_changes
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
map_tempfile = pytest.helpers.temp_file(
|
||||
"test/map.jinja", map_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"test.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
|
||||
with top_tempfile, map_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def nested_state_tree(base_env_state_tree_root_dir, tmp_path):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- basic
|
||||
'127.0.0.1':
|
||||
- basic
|
||||
"""
|
||||
state_file = """
|
||||
/{}/file.txt:
|
||||
file.managed:
|
||||
- source: salt://foo/file.jinja
|
||||
- template: jinja
|
||||
""".format(
|
||||
tmp_path
|
||||
)
|
||||
file_jinja = """
|
||||
{% from 'foo/map.jinja' import comment %}{{ comment }}
|
||||
"""
|
||||
map_file = """
|
||||
{% set comment = "blah blah" %}
|
||||
"""
|
||||
statedir = base_env_state_tree_root_dir / "foo"
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
map_tempfile = pytest.helpers.temp_file("map.jinja", map_file, statedir)
|
||||
file_tempfile = pytest.helpers.temp_file("file.jinja", file_jinja, statedir)
|
||||
state_tempfile = pytest.helpers.temp_file("init.sls", state_file, statedir)
|
||||
|
||||
with top_tempfile, map_tempfile, state_tempfile, file_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def pillar_tree_nested(base_env_pillar_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- nested
|
||||
'127.0.0.1':
|
||||
- nested
|
||||
"""
|
||||
nested_pillar = r"""
|
||||
{%- do salt.log.warning("hithere: pillar was rendered") %}
|
||||
monty: python
|
||||
the_meaning:
|
||||
of:
|
||||
life: 42
|
||||
bar: tender
|
||||
for: what
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_pillar_tree_root_dir
|
||||
)
|
||||
nested_tempfile = pytest.helpers.temp_file(
|
||||
"nested.sls", nested_pillar, base_env_pillar_tree_root_dir
|
||||
)
|
||||
with top_tempfile, nested_tempfile:
|
||||
yield
|
189
tests/pytests/integration/ssh/state/test_pillar_override.py
Normal file
189
tests/pytests/integration/ssh/state/test_pillar_override.py
Normal file
|
@ -0,0 +1,189 @@
|
|||
"""
|
||||
Ensure pillar overrides are merged recursively, that wrapper
|
||||
modules are in sync with the pillar dict in the rendering environment
|
||||
and that the pillars are available on the target.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.utils.dictupdate
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.usefixtures("pillar_tree_nested"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
def test_pillar_is_only_rendered_once_without_overrides(salt_ssh_cli, caplog):
|
||||
ret = salt_ssh_cli.run("state.apply", "test")
|
||||
assert ret.returncode == 0
|
||||
assert isinstance(ret.data, dict)
|
||||
assert ret.data
|
||||
assert ret.data[next(iter(ret.data))]["result"] is True
|
||||
assert caplog.text.count("hithere: pillar was rendered") == 1
|
||||
|
||||
|
||||
def test_pillar_is_rerendered_with_overrides(salt_ssh_cli, caplog):
|
||||
ret = salt_ssh_cli.run("state.apply", "test", pillar={"foo": "bar"})
|
||||
assert ret.returncode == 0
|
||||
assert isinstance(ret.data, dict)
|
||||
assert ret.data
|
||||
assert ret.data[next(iter(ret.data))]["result"] is True
|
||||
assert caplog.text.count("hithere: pillar was rendered") == 2
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def _show_pillar_state(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- showpillar
|
||||
'127.0.0.1':
|
||||
- showpillar
|
||||
"""
|
||||
show_pillar_sls = """
|
||||
deep_thought:
|
||||
test.show_notification:
|
||||
- text: '{{ {
|
||||
"raw": {
|
||||
"the_meaning": pillar.get("the_meaning"),
|
||||
"btw": pillar.get("btw")},
|
||||
"wrapped": {
|
||||
"the_meaning": salt["pillar.get"]("the_meaning"),
|
||||
"btw": salt["pillar.get"]("btw")}}
|
||||
| json }}'
|
||||
|
||||
target_check:
|
||||
test.check_pillar:
|
||||
- present:
|
||||
- the_meaning:of:foo
|
||||
- btw
|
||||
- the_meaning:of:bar
|
||||
- the_meaning:for
|
||||
- listing:
|
||||
- the_meaning:of:life
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
show_tempfile = pytest.helpers.temp_file(
|
||||
"showpillar.sls", show_pillar_sls, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, show_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def base():
|
||||
return {"the_meaning": {"of": {"life": 42, "bar": "tender"}, "for": "what"}}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def override(base):
|
||||
poverride = {
|
||||
"the_meaning": {"of": {"life": [2.71], "foo": "lish"}},
|
||||
"btw": "turtles",
|
||||
}
|
||||
expected = salt.utils.dictupdate.merge(base, poverride)
|
||||
return expected, poverride
|
||||
|
||||
|
||||
def test_state_sls(salt_ssh_cli, override):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run("state.sls", "showpillar", pillar=override)
|
||||
_assert_basic(ret)
|
||||
assert len(ret.data) == 2
|
||||
for sid, sret in ret.data.items():
|
||||
if "show" in sid:
|
||||
_assert_pillar(sret["comment"], expected)
|
||||
else:
|
||||
assert sret["result"] is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("sid", ("deep_thought", "target_check"))
|
||||
def test_state_sls_id(salt_ssh_cli, sid, override):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run("state.sls_id", sid, "showpillar", pillar=override)
|
||||
_assert_basic(ret)
|
||||
state_res = ret.data[next(iter(ret.data))]
|
||||
if sid == "deep_thought":
|
||||
_assert_pillar(state_res["comment"], expected)
|
||||
else:
|
||||
assert state_res["result"] is True
|
||||
|
||||
|
||||
def test_state_highstate(salt_ssh_cli, override):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run("state.highstate", pillar=override, whitelist=["showpillar"])
|
||||
_assert_basic(ret)
|
||||
assert len(ret.data) == 2
|
||||
for sid, sret in ret.data.items():
|
||||
if "show" in sid:
|
||||
_assert_pillar(sret["comment"], expected)
|
||||
else:
|
||||
assert sret["result"] is True
|
||||
|
||||
|
||||
def test_state_show_sls(salt_ssh_cli, override):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run("state.show_sls", "showpillar", pillar=override)
|
||||
_assert_basic(ret)
|
||||
pillar = ret.data["deep_thought"]["test"]
|
||||
pillar = next(x["text"] for x in pillar if isinstance(x, dict))
|
||||
_assert_pillar(pillar, expected)
|
||||
|
||||
|
||||
def test_state_show_low_sls(salt_ssh_cli, override):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run("state.show_low_sls", "showpillar", pillar=override)
|
||||
_assert_basic(ret, list)
|
||||
pillar = ret.data[0]["text"]
|
||||
_assert_pillar(pillar, expected)
|
||||
|
||||
|
||||
def test_state_single(salt_ssh_cli, override):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run(
|
||||
"state.single",
|
||||
"test.check_pillar",
|
||||
"foo",
|
||||
present=[
|
||||
"the_meaning:of:foo",
|
||||
"btw",
|
||||
"the_meaning:of:bar",
|
||||
"the_meaning:for",
|
||||
],
|
||||
listing=["the_meaning:of:life"],
|
||||
pillar=override,
|
||||
)
|
||||
_assert_basic(ret, dict)
|
||||
state_res = ret.data[next(iter(ret.data))]
|
||||
assert state_res["result"] is True
|
||||
|
||||
|
||||
def test_state_top(salt_ssh_cli, override):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run("state.top", "top.sls", pillar=override)
|
||||
_assert_basic(ret)
|
||||
assert len(ret.data) == 2
|
||||
for sid, sret in ret.data.items():
|
||||
if "show" in sid:
|
||||
_assert_pillar(sret["comment"], expected)
|
||||
else:
|
||||
assert sret["result"] is True
|
||||
|
||||
|
||||
def _assert_pillar(pillar, expected):
|
||||
if not isinstance(pillar, dict):
|
||||
pillar = json.loads(pillar)
|
||||
assert pillar["raw"] == expected
|
||||
assert pillar["wrapped"] == expected
|
||||
|
||||
|
||||
def _assert_basic(ret, typ=dict):
|
||||
assert ret.returncode == 0
|
||||
assert isinstance(ret.data, typ)
|
||||
assert ret.data
|
|
@ -0,0 +1,97 @@
|
|||
"""
|
||||
Specifically ensure that pillars are merged as expected
|
||||
for the target as well and available for renderers.
|
||||
This should be covered by `test.check_pillar` above, but
|
||||
let's check the specific output for the most important funcs.
|
||||
Issue #59802
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.utils.dictupdate
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.usefixtures("pillar_tree_nested"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _write_pillar_state(base_env_state_tree_root_dir, tmp_path_factory):
|
||||
tmp_path = tmp_path_factory.mktemp("tgtdir")
|
||||
tgt_file = tmp_path / "deepthought.txt"
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- writepillar
|
||||
'127.0.0.1':
|
||||
- writepillar
|
||||
"""
|
||||
nested_pillar_file = f"""
|
||||
deep_thought:
|
||||
file.managed:
|
||||
- name: {tgt_file}
|
||||
- source: salt://deepthought.txt.jinja
|
||||
- template: jinja
|
||||
"""
|
||||
deepthought = r"""
|
||||
{{
|
||||
{
|
||||
"raw": {
|
||||
"the_meaning": pillar.get("the_meaning"),
|
||||
"btw": pillar.get("btw")},
|
||||
"modules": {
|
||||
"the_meaning": salt["pillar.get"]("the_meaning"),
|
||||
"btw": salt["pillar.get"]("btw")}
|
||||
} | json }}
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
show_tempfile = pytest.helpers.temp_file(
|
||||
"writepillar.sls", nested_pillar_file, base_env_state_tree_root_dir
|
||||
)
|
||||
deepthought_tempfile = pytest.helpers.temp_file(
|
||||
"deepthought.txt.jinja", deepthought, base_env_state_tree_root_dir
|
||||
)
|
||||
|
||||
with top_tempfile, show_tempfile, deepthought_tempfile:
|
||||
yield tgt_file
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def base():
|
||||
return {"the_meaning": {"of": {"life": 42, "bar": "tender"}, "for": "what"}}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def override(base):
|
||||
poverride = {
|
||||
"the_meaning": {"of": {"life": 2.71, "foo": "lish"}},
|
||||
"btw": "turtles",
|
||||
}
|
||||
expected = salt.utils.dictupdate.merge(base, poverride)
|
||||
return expected, poverride
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args,kwargs",
|
||||
(
|
||||
(("state.sls", "writepillar"), {}),
|
||||
(("state.highstate",), {"whitelist": "writepillar"}),
|
||||
(("state.top", "top.sls"), {}),
|
||||
),
|
||||
)
|
||||
def test_it(salt_ssh_cli, args, kwargs, override, _write_pillar_state):
|
||||
expected, override = override
|
||||
ret = salt_ssh_cli.run(*args, **kwargs, pillar=override)
|
||||
assert ret.returncode == 0
|
||||
assert isinstance(ret.data, dict)
|
||||
assert ret.data
|
||||
assert _write_pillar_state.exists()
|
||||
pillar = json.loads(_write_pillar_state.read_text())
|
||||
assert pillar["raw"] == expected
|
||||
assert pillar["modules"] == expected
|
|
@ -0,0 +1,62 @@
|
|||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a highstate verification fails.
|
||||
``state.show_highstate`` does not validate this.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from salt.defaults.exitcodes import EX_AGGREGATE
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def state_tree_req_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_req
|
||||
'127.0.0.1':
|
||||
- fail_req
|
||||
"""
|
||||
state_file = """
|
||||
This has an invalid requisite:
|
||||
test.nop:
|
||||
- name: foo
|
||||
- require_in:
|
||||
- file.managed: invalid_requisite
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_req.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args,retcode",
|
||||
(
|
||||
(("state.sls", "fail_req"), EX_AGGREGATE),
|
||||
(("state.highstate",), EX_AGGREGATE),
|
||||
(("state.show_sls", "fail_req"), EX_AGGREGATE),
|
||||
(("state.show_low_sls", "fail_req"), EX_AGGREGATE),
|
||||
# state.show_lowstate exits with 0 for non-ssh as well
|
||||
(("state.show_lowstate",), 0),
|
||||
(("state.top", "top.sls"), EX_AGGREGATE),
|
||||
),
|
||||
)
|
||||
def test_it(salt_ssh_cli, args, retcode):
|
||||
ret = salt_ssh_cli.run(*args)
|
||||
assert ret.returncode == retcode
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0].startswith(
|
||||
"Invalid requisite in require: file.managed for invalid_requisite"
|
||||
)
|
|
@ -0,0 +1,64 @@
|
|||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a highstate verification fails.
|
||||
This targets another step of the verification.
|
||||
``state.sls_id`` does not seem to support extends.
|
||||
``state.show_highstate`` does not validate this.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from salt.defaults.exitcodes import EX_AGGREGATE
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def state_tree_structure_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_structure
|
||||
'127.0.0.1':
|
||||
- fail_structure
|
||||
"""
|
||||
state_file = """
|
||||
extend:
|
||||
Some file state:
|
||||
file:
|
||||
- name: /tmp/bar
|
||||
- contents: bar
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_structure.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args,retcode",
|
||||
(
|
||||
(("state.sls", "fail_structure"), EX_AGGREGATE),
|
||||
(("state.highstate",), EX_AGGREGATE),
|
||||
(("state.show_sls", "fail_structure"), EX_AGGREGATE),
|
||||
(("state.show_low_sls", "fail_structure"), EX_AGGREGATE),
|
||||
# state.show_lowstate exits with 0 for non-ssh as well
|
||||
(("state.show_lowstate",), 0),
|
||||
(("state.top", "top.sls"), EX_AGGREGATE),
|
||||
),
|
||||
)
|
||||
def test_it(salt_ssh_cli, args, retcode):
|
||||
ret = salt_ssh_cli.run(*args)
|
||||
assert ret.returncode == retcode
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0].startswith(
|
||||
"Cannot extend ID 'Some file state' in 'base:fail_structure"
|
||||
)
|
|
@ -0,0 +1,57 @@
|
|||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a pillar rendering fails.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from salt.defaults.exitcodes import EX_AGGREGATE
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def pillar_tree_render_fail(base_env_pillar_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_render
|
||||
'127.0.0.1':
|
||||
- fail_render
|
||||
"""
|
||||
pillar_file = r"""
|
||||
not_defined: {{ abc }}
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_pillar_tree_root_dir
|
||||
)
|
||||
pillar_tempfile = pytest.helpers.temp_file(
|
||||
"fail_render.sls", pillar_file, base_env_pillar_tree_root_dir
|
||||
)
|
||||
with top_tempfile, pillar_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args",
|
||||
(
|
||||
("state.sls", "basic"),
|
||||
("state.highstate",),
|
||||
("state.sls_id", "foo", "basic"),
|
||||
("state.show_sls", "basic"),
|
||||
("state.show_low_sls", "basic"),
|
||||
("state.show_highstate",),
|
||||
("state.show_lowstate",),
|
||||
("state.top", "top.sls"),
|
||||
),
|
||||
)
|
||||
def test_it(salt_ssh_cli, args):
|
||||
ret = salt_ssh_cli.run(*args)
|
||||
assert ret.returncode == EX_AGGREGATE
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0] == "Pillar failed to render with the following messages:"
|
||||
assert ret.data[1].startswith("Rendering SLS 'fail_render' failed.")
|
|
@ -0,0 +1,67 @@
|
|||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a state rendering fails.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from salt.defaults.exitcodes import EX_AGGREGATE
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def state_tree_render_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_render
|
||||
'127.0.0.1':
|
||||
- fail_render
|
||||
"""
|
||||
state_file = r"""
|
||||
abc var is not defined {{ abc }}:
|
||||
test.nop
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_render.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args,retcode",
|
||||
(
|
||||
(("state.sls", "fail_render"), EX_AGGREGATE),
|
||||
(("state.highstate",), EX_AGGREGATE),
|
||||
(("state.sls_id", "foo", "fail_render"), EX_AGGREGATE),
|
||||
(("state.show_sls", "fail_render"), EX_AGGREGATE),
|
||||
(("state.show_low_sls", "fail_render"), EX_AGGREGATE),
|
||||
(("state.show_highstate",), EX_AGGREGATE),
|
||||
# state.show_lowstate exits with 0 for non-ssh as well
|
||||
(("state.show_lowstate",), 0),
|
||||
(("state.top", "top.sls"), EX_AGGREGATE),
|
||||
),
|
||||
)
|
||||
def test_it(salt_ssh_cli, args, retcode):
|
||||
ret = salt_ssh_cli.run(*args)
|
||||
assert ret.returncode == retcode
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0].startswith(
|
||||
"Rendering SLS 'base:fail_render' failed: Jinja variable 'abc' is undefined;"
|
||||
)
|
||||
|
||||
|
||||
def test_state_single(salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.single", "file")
|
||||
assert ret.returncode == EX_AGGREGATE
|
||||
assert isinstance(ret.data, str)
|
||||
assert "single() missing 1 required positional argument" in ret.data
|
52
tests/pytests/integration/ssh/state/test_retcode_run_fail.py
Normal file
52
tests/pytests/integration/ssh/state/test_retcode_run_fail.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
"""
|
||||
Verify salt-ssh passes on a failing retcode from state execution.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from salt.defaults.exitcodes import EX_AGGREGATE
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def state_tree_run_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_run
|
||||
'127.0.0.1':
|
||||
- fail_run
|
||||
"""
|
||||
state_file = """
|
||||
This file state fails:
|
||||
file.managed:
|
||||
- name: /tmp/non/ex/is/tent
|
||||
- makedirs: false
|
||||
- contents: foo
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_run.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args",
|
||||
(
|
||||
("state.sls", "fail_run"),
|
||||
("state.highstate",),
|
||||
("state.sls_id", "This file state fails", "fail_run"),
|
||||
("state.top", "top.sls"),
|
||||
),
|
||||
)
|
||||
def test_it(salt_ssh_cli, args):
|
||||
ret = salt_ssh_cli.run(*args)
|
||||
assert ret.returncode == EX_AGGREGATE
|
103
tests/pytests/integration/ssh/state/test_state.py
Normal file
103
tests/pytests/integration/ssh/state/test_state.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
import pytest
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
pytest.mark.slow_test,
|
||||
]
|
||||
|
||||
|
||||
def test_state_with_import(salt_ssh_cli, state_tree):
|
||||
"""
|
||||
verify salt-ssh can use imported map files in states
|
||||
"""
|
||||
ret = salt_ssh_cli.run("state.sls", "test")
|
||||
assert ret.returncode == 0
|
||||
assert ret.data
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"ssh_cmd",
|
||||
[
|
||||
"state.sls",
|
||||
"state.highstate",
|
||||
"state.apply",
|
||||
"state.show_top",
|
||||
"state.show_highstate",
|
||||
"state.show_low_sls",
|
||||
"state.show_lowstate",
|
||||
"state.sls_id",
|
||||
"state.show_sls",
|
||||
"state.top",
|
||||
],
|
||||
)
|
||||
def test_state_with_import_dir(salt_ssh_cli, state_tree_dir, ssh_cmd):
|
||||
"""
|
||||
verify salt-ssh can use imported map files in states
|
||||
when the map files are in another directory outside of
|
||||
sls files importing them.
|
||||
"""
|
||||
if ssh_cmd in ("state.sls", "state.show_low_sls", "state.show_sls"):
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "test")
|
||||
elif ssh_cmd == "state.top":
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "top.sls")
|
||||
elif ssh_cmd == "state.sls_id":
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "Ok with def", "test")
|
||||
else:
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd)
|
||||
assert ret.returncode == 0
|
||||
if ssh_cmd == "state.show_top":
|
||||
assert ret.data == {"base": ["test", "master_tops_test"]} or {"base": ["test"]}
|
||||
elif ssh_cmd in ("state.show_highstate", "state.show_sls"):
|
||||
assert ret.data == {
|
||||
"Ok with def": {
|
||||
"__sls__": "test",
|
||||
"__env__": "base",
|
||||
"test": ["succeed_without_changes", {"order": 10000}],
|
||||
}
|
||||
}
|
||||
elif ssh_cmd in ("state.show_low_sls", "state.show_lowstate", "state.show_sls"):
|
||||
assert ret.data == [
|
||||
{
|
||||
"state": "test",
|
||||
"name": "Ok with def",
|
||||
"__sls__": "test",
|
||||
"__env__": "base",
|
||||
"__id__": "Ok with def",
|
||||
"order": 10000,
|
||||
"fun": "succeed_without_changes",
|
||||
}
|
||||
]
|
||||
else:
|
||||
assert ret.data["test_|-Ok with def_|-Ok with def_|-succeed_without_changes"][
|
||||
"result"
|
||||
]
|
||||
assert ret.data
|
||||
|
||||
|
||||
def test_state_with_import_from_dir(salt_ssh_cli, nested_state_tree):
|
||||
"""
|
||||
verify salt-ssh can use imported map files in states
|
||||
"""
|
||||
ret = salt_ssh_cli.run(
|
||||
"--extra-filerefs=salt://foo/map.jinja", "state.apply", "foo"
|
||||
)
|
||||
assert ret.returncode == 0
|
||||
assert ret.data
|
||||
|
||||
|
||||
def test_state_low(salt_ssh_cli):
|
||||
"""
|
||||
test state.low with salt-ssh
|
||||
"""
|
||||
ret = salt_ssh_cli.run(
|
||||
"state.low", '{"state": "cmd", "fun": "run", "name": "echo blah"}'
|
||||
)
|
||||
assert ret.data["cmd_|-echo blah_|-echo blah_|-run"]["changes"]["stdout"] == "blah"
|
||||
|
||||
|
||||
def test_state_high(salt_ssh_cli):
|
||||
"""
|
||||
test state.high with salt-ssh
|
||||
"""
|
||||
ret = salt_ssh_cli.run("state.high", '{"echo blah": {"cmd": ["run"]}}')
|
||||
assert ret.data["cmd_|-echo blah_|-echo blah_|-run"]["changes"]["stdout"] == "blah"
|
241
tests/pytests/integration/ssh/test_pillar_compilation.py
Normal file
241
tests/pytests/integration/ssh/test_pillar_compilation.py
Normal file
|
@ -0,0 +1,241 @@
|
|||
import logging
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
from pytestshellutils.utils.processes import ProcessResult
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# The following fixtures are copied from pytests/functional/pillar/test_gpg.py
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def test_key():
|
||||
"""
|
||||
Private key for setting up GPG pillar environment.
|
||||
"""
|
||||
return textwrap.dedent(
|
||||
"""\
|
||||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
lQOYBFiKrcYBCADAj92+fz20uKxxH0ffMwcryGG9IogkiUi2QrNYilB4hwrY5Qt7
|
||||
Sbywlk/mSDMcABxMxS0vegqc5pgglvAnsi9w7j//9nfjiirsyiTYOOD1akTFQr7b
|
||||
qT6zuGFA4oYmYHvfBOena485qvlyitYLKYT9h27TDiiH6Jgt4xSRbjeyhTf3/fKD
|
||||
JzHA9ii5oeVi1pH/8/4USgXanBdKwO0JKQtci+PF0qe/nkzRswqTIkdgx1oyNUqL
|
||||
tYJ0XPOy+UyOC4J4QDIt9PQbAmiur8By4g2lLYWlGOCjs7Fcj3n5meWKzf1pmXoY
|
||||
lAnSab8kUZSSkoWQoTO7RbjFypULKCZui45/ABEBAAEAB/wM1wsAMtfYfx/wgxd1
|
||||
yJ9HyhrKU80kMotIq/Xth3uKLecJQ2yakfYlCEDXqCTQTymT7OnwaoDeqXmnYqks
|
||||
3HLRYvGdjb+8ym/GTkxapqBJfQaM6MB1QTnPHhJOE0zCrlhULK2NulxYihAMFTnk
|
||||
kKYviaJYLG+DcH0FQkkS0XihTKcqnsoJiS6iNd5SME3pa0qijR0D5f78fkvNzzEE
|
||||
9vgAX1TgQ5PDJGN6nYlW2bWxTcg+FR2cUAQPTiP9wXCH6VyJoQay7KHVr3r/7SsU
|
||||
89otfcx5HVDYPrez6xnP6wN0P/mKxCDbkERLDjZjWOmNXg2zn+/t3u02e+ybfAIp
|
||||
kTTxBADY/FmPgLpJ2bpcPH141twpHwhKIbENlTB9745Qknr6aLA0QVCkz49/3joO
|
||||
Sj+SZ7Jhl6cfbynrfHwX3b1bOFTzBUH2Tsi0HX40PezEFH0apf55FLZuMOBt/lc1
|
||||
ET6evpIHF0dcM+BvZa7E7MyTyEq8S7Cc9RoJyfeGbS7MG5FfuwQA4y9QOb/OQglq
|
||||
ZffkVItwY52RKWb/b2WQmt+IcVax/j7DmBva765SIfPDvOCMrYhJBI/uYHQ0Zia7
|
||||
SnC9+ez55wdYqgHkYojc21CIOnUvsPSj+rOpryoXzmcTuvKeVIyIA0h/mQyWjimR
|
||||
ENrikC4+O8GBMY6V4uvS4EFhLfHE9g0D/20lNOKkpAKPenr8iAPWcl0/pijJCGxF
|
||||
agnT7O2GQ9Lr5hSjW86agkevbGktu2ja5t/fHq0wpLQ4DVLMrR0/poaprTr307kW
|
||||
AlQV3z/C2cMHNysz4ulOgQrudQbhUEz2A8nQxRtIfWunkEugKLr1QiCkE1LJW8Np
|
||||
ZLxE6Qp0/KzdQva0HVNhbHQgR1BHIDxlcmlrQHNhbHRzdGFjay5jb20+iQFUBBMB
|
||||
CAA+FiEE+AxQ1ELHGEyFTZPYw5x3k9EbHGsFAliKrcYCGwMFCQPCZwAFCwkIBwIG
|
||||
FQgJCgsCBBYCAwECHgECF4AACgkQw5x3k9EbHGubUAf+PLdp1oTLVokockZgLyIQ
|
||||
wxOd3ofNOgNk4QoAkSMNSbtnYoQFKumRw/yGyPSIoHMsOC/ga98r8TAJEKfx3DLA
|
||||
rsD34oMAaYUT+XUd0KoSmlHqBrtDD1+eBASKYsCosHpCiKuQFfLKSxvpEr2YyL8L
|
||||
X3Q2TY5zFlGA9Eeq5g+rlb++yRZrruFN28EWtY/pyXFZgIB30ReDwPkM9hrioPZM
|
||||
0Qf3+dWZSK1rWViclB51oNy4un9stTiFZptAqz4NTNssU5A4AcNQPwBwnKIYoE58
|
||||
Y/Zyv8HzILGykT+qFebqRlRBI/13eHdzgJOL1iPRfjTk5Cvr+vcyIxAklXOP81ja
|
||||
B50DmARYiq3GAQgArnzu4SPCCQGNcCNxN4QlMP5TNvRsm5KrPbcO9j8HPfB+DRXs
|
||||
6B3mnuR6OJg7YuC0C2A/m2dSHJKkF0f2AwFRpxLjJ2iAFbrZAW/N0vZDx8zO+YAU
|
||||
HyLu0V04wdCE5DTLkgfWNR+0uMa8qZ4Kn56Gv7O+OFE7zgTHeZ7psWlxdafeW7u6
|
||||
zlC/3DWksNtuNb0vQDNMM4vgXbnORIfXdyh41zvEEnr/rKw8DuJAmo20mcv6Qi51
|
||||
PqqyM62ddQOEVfiMs9l4vmwZAjGFNFNInyPXnogL6UPCDmizb6hh8aX/MwG/XFIG
|
||||
KMJWbAVGpyBuqljKIt3qLu/s8ouPqkEN+f+nGwARAQABAAf+NA36d/kieGxZpTQ1
|
||||
oQHP1Jty+OiXhBwP8SPtF0J7ZxuZh07cs+zDsfBok/y6bsepfuFSaIq84OBQis+B
|
||||
kajxkp3cXZPb7l+lQLv5k++7Dd7Ien+ewSE7TQN6HLwYATrM5n5nBcc1M5C6lQGc
|
||||
mr0A5yz42TVG2bHsTpi9kBtsaVRSPUHSh8A8T6eOyCrT+/CAJVEEf7JyNyaqH1dy
|
||||
LuxI1VF3ySDEtFzuwN8EZQP9Yz/4AVyEQEA7WkNEwSQsBi2bWgWEdG+qjqnL+YKa
|
||||
vwe7/aJYPeL1zICnP/Osd/UcpDxR78MbozstbRljML0fTLj7UJ+XDazwv+Kl0193
|
||||
2ZK2QQQAwgXvS19MYNkHO7kbNVLt1VE2ll901iC9GFHBpFUam6gmoHXpCarB+ShH
|
||||
8x25aoUu4MxHmFxXd+Zq3d6q2yb57doWoPgvqcefpGmigaITnb1jhV2rt65V8deA
|
||||
SQazZNqBEBbZNIhfn6ObxHXXvaYaqq/UOEQ7uKyR9WMJT/rmqMEEAOY5h1R1t7AB
|
||||
JZ5VnhyAhdsNWw1gTcXB3o8gKz4vjdnPm0F4aVIPfB3BukETDc3sc2tKmCfUF7I7
|
||||
oOrh7iRez5F0RIC3KDzXF8qUuWBfPViww45JgftdKsecCIlEEYCoc+3goX0su2bP
|
||||
V1MDuHijMGTJCBABDgizNb0oynW5xcrbA/0QnKfpTwi7G3oRcJWv2YebVDRcU+SP
|
||||
dOYhq6SnmWPizEIljRG/X7FHJB+W7tzryO3sCDTAYwxFrfMwvJ2PwnAYI4349zYd
|
||||
lC28HowUkBYNhwBXc48xCfyhPZtD0aLx/OX1oLZ/vi8gd8TusgGupV/JjkFVO+Nd
|
||||
+shN/UEAldwqkkY2iQE8BBgBCAAmFiEE+AxQ1ELHGEyFTZPYw5x3k9EbHGsFAliK
|
||||
rcYCGwwFCQPCZwAACgkQw5x3k9EbHGu4wwf/dRFat91BRX1TJfwJl5otoAXpItYM
|
||||
6kdWWf1Eb1BicAvXhI078MSH4WXdKkJjJr1fFP8Ynil513H4Mzb0rotMAhb0jLSA
|
||||
lSRkMbhMvPxoS2kaYzioaBpp8yXpGiNo7dF+PJXSm/Uwp3AkcFjoVbBOqDWGgxMi
|
||||
DvDAstzLZ9dIcmr+OmcRQykKOKXlhEl3HnR5CyuPrA8hdVup4oeVwdkJhfJFKLLb
|
||||
3fR26wxJOmIOAt24eAUy721WfQ9txNAmhdy8mY842ODZESw6WatrQjRfuqosDgrk
|
||||
jc0cCHsEqJNZ2AB+1uEl3tcH0tyAFJa33F0znSonP17SS1Ff9sgHYBVLUg==
|
||||
=06Tz
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def gpg_pillar_yaml():
|
||||
"""
|
||||
Yaml data for testing GPG pillar.
|
||||
"""
|
||||
return textwrap.dedent(
|
||||
"""
|
||||
#!yaml|gpg
|
||||
secrets:
|
||||
foo: |
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
hQEMAw2B674HRhwSAQgAhTrN8NizwUv/VunVrqa4/X8t6EUulrnhKcSeb8sZS4th
|
||||
W1Qz3K2NjL4lkUHCQHKZVx/VoZY7zsddBIFvvoGGfj8+2wjkEDwFmFjGE4DEsS74
|
||||
ZLRFIFJC1iB/O0AiQ+oU745skQkU6OEKxqavmKMrKo3rvJ8ZCXDC470+i2/Hqrp7
|
||||
+KWGmaDOO422JaSKRm5D9bQZr9oX7KqnrPG9I1+UbJyQSJdsdtquPWmeIpamEVHb
|
||||
VMDNQRjSezZ1yKC4kCWm3YQbBF76qTHzG1VlLF5qOzuGI9VkyvlMaLfMibriqY73
|
||||
zBbPzf6Bkp2+Y9qyzuveYMmwS4sEOuZL/PetqisWe9JGAWD/O+slQ2KRu9hNww06
|
||||
KMDPJRdyj5bRuBVE4hHkkP23KrYr7SuhW2vpe7O/MvWEJ9uDNegpMLhTWruGngJh
|
||||
iFndxegN9w==
|
||||
=bAuo
|
||||
-----END PGP MESSAGE-----
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def gpg_homedir(salt_master, test_key):
|
||||
"""
|
||||
Setup gpg environment
|
||||
"""
|
||||
_gpg_homedir = pathlib.Path(salt_master.config_dir) / "gpgkeys"
|
||||
_gpg_homedir.mkdir(0o700)
|
||||
agent_started = False
|
||||
try:
|
||||
cmd_prefix = ["gpg", "--homedir", str(_gpg_homedir)]
|
||||
|
||||
cmd = cmd_prefix + ["--list-keys"]
|
||||
proc = subprocess.run(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
check=True,
|
||||
universal_newlines=True,
|
||||
)
|
||||
ret = ProcessResult(
|
||||
returncode=proc.returncode,
|
||||
stdout=proc.stdout,
|
||||
stderr=proc.stderr or "",
|
||||
cmdline=proc.args,
|
||||
)
|
||||
log.debug("Instantiating gpg keyring...\n%s", ret)
|
||||
|
||||
cmd = cmd_prefix + ["--import", "--allow-secret-key-import"]
|
||||
proc = subprocess.run(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
check=True,
|
||||
universal_newlines=True,
|
||||
input=test_key,
|
||||
)
|
||||
ret = ProcessResult(
|
||||
returncode=proc.returncode,
|
||||
stdout=proc.stdout,
|
||||
stderr=proc.stderr or "",
|
||||
cmdline=proc.args,
|
||||
)
|
||||
log.debug("Importing keypair...:\n%s", ret)
|
||||
|
||||
agent_started = True
|
||||
|
||||
yield _gpg_homedir
|
||||
finally:
|
||||
if agent_started:
|
||||
try:
|
||||
cmd = ["gpg-connect-agent", "--homedir", str(_gpg_homedir)]
|
||||
proc = subprocess.run(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
check=True,
|
||||
universal_newlines=True,
|
||||
input="KILLAGENT",
|
||||
)
|
||||
ret = ProcessResult(
|
||||
returncode=proc.returncode,
|
||||
stdout=proc.stdout,
|
||||
stderr=proc.stderr or "",
|
||||
cmdline=proc.args,
|
||||
)
|
||||
log.debug("Killed gpg-agent...\n%s", ret)
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
log.debug("No need to kill: old gnupg doesn't start the agent.")
|
||||
shutil.rmtree(str(_gpg_homedir), ignore_errors=True)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def pillar_setup(base_env_pillar_tree_root_dir, gpg_pillar_yaml, salt_minion):
|
||||
"""
|
||||
Setup gpg pillar
|
||||
"""
|
||||
saltutil_contents = f"""
|
||||
saltutil: {{{{ salt["saltutil.runner"]("mine.get", tgt="{salt_minion.id}", fun="test.ping") | json }}}}
|
||||
"""
|
||||
top_file_contents = """
|
||||
base:
|
||||
'*':
|
||||
- gpg
|
||||
- saltutil
|
||||
"""
|
||||
with pytest.helpers.temp_file(
|
||||
"top.sls", top_file_contents, base_env_pillar_tree_root_dir
|
||||
), pytest.helpers.temp_file(
|
||||
"gpg.sls", gpg_pillar_yaml, base_env_pillar_tree_root_dir
|
||||
), pytest.helpers.temp_file(
|
||||
"saltutil.sls", saltutil_contents, base_env_pillar_tree_root_dir
|
||||
):
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.skip_if_binaries_missing("gpg")
|
||||
@pytest.mark.usefixtures("pillar_setup", "gpg_homedir")
|
||||
def test_gpg_pillar(salt_ssh_cli):
|
||||
"""
|
||||
Ensure that GPG-encrypted pillars can be decrypted, i.e. the
|
||||
gpg_keydir should not be overridden. This is issue #60002,
|
||||
which has the same cause as the one below.
|
||||
"""
|
||||
ret = salt_ssh_cli.run("pillar.items")
|
||||
assert ret.returncode == 0
|
||||
assert isinstance(ret.data, dict)
|
||||
assert ret.data
|
||||
assert "secrets" in ret.data
|
||||
assert "foo" in ret.data["secrets"]
|
||||
assert "BEGIN PGP MESSAGE" not in ret.data["secrets"]["foo"]
|
||||
assert ret.data["secrets"]["foo"] == "supersecret"
|
||||
assert "_errors" not in ret.data
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("pillar_setup")
|
||||
def test_saltutil_runner(salt_ssh_cli, salt_minion, salt_run_cli):
|
||||
"""
|
||||
Ensure that during pillar compilation, the cache dir is not
|
||||
overridden. For a history, see PR #50489 and issue #36796,
|
||||
notice that the initial description is probably unrelated
|
||||
to this.
|
||||
"""
|
||||
ret = salt_ssh_cli.run("pillar.items")
|
||||
assert ret.returncode == 0
|
||||
assert isinstance(ret.data, dict)
|
||||
assert ret.data
|
||||
assert "saltutil" in ret.data
|
||||
assert isinstance(ret.data["saltutil"], dict)
|
||||
assert ret.data["saltutil"]
|
||||
assert salt_minion.id in ret.data["saltutil"]
|
||||
assert ret.data["saltutil"][salt_minion.id] is True
|
||||
assert "_errors" not in ret.data
|
|
@ -1,563 +0,0 @@
|
|||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from salt.defaults.exitcodes import EX_AGGREGATE
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_on_windows(reason="salt-ssh not available on Windows"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def state_tree(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
{%- from "map.jinja" import abc with context %}
|
||||
base:
|
||||
'localhost':
|
||||
- basic
|
||||
'127.0.0.1':
|
||||
- basic
|
||||
"""
|
||||
map_file = """
|
||||
{%- set abc = "def" %}
|
||||
"""
|
||||
state_file = """
|
||||
{%- from "map.jinja" import abc with context %}
|
||||
Ok with {{ abc }}:
|
||||
test.succeed_without_changes
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
map_tempfile = pytest.helpers.temp_file(
|
||||
"map.jinja", map_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"test.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, map_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def state_tree_dir(base_env_state_tree_root_dir):
|
||||
"""
|
||||
State tree with files to test salt-ssh
|
||||
when the map.jinja file is in another directory
|
||||
"""
|
||||
top_file = """
|
||||
{%- from "test/map.jinja" import abc with context %}
|
||||
base:
|
||||
'localhost':
|
||||
- test
|
||||
'127.0.0.1':
|
||||
- test
|
||||
"""
|
||||
map_file = """
|
||||
{%- set abc = "def" %}
|
||||
"""
|
||||
state_file = """
|
||||
{%- from "test/map.jinja" import abc with context %}
|
||||
|
||||
Ok with {{ abc }}:
|
||||
test.succeed_without_changes
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
map_tempfile = pytest.helpers.temp_file(
|
||||
"test/map.jinja", map_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"test.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
|
||||
with top_tempfile, map_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def state_tree_render_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_render
|
||||
'127.0.0.1':
|
||||
- fail_render
|
||||
"""
|
||||
state_file = r"""
|
||||
abc var is not defined {{ abc }}:
|
||||
test.nop
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_render.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def state_tree_req_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_req
|
||||
'127.0.0.1':
|
||||
- fail_req
|
||||
"""
|
||||
state_file = """
|
||||
This has an invalid requisite:
|
||||
test.nop:
|
||||
- name: foo
|
||||
- require_in:
|
||||
- file.managed: invalid_requisite
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_req.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def state_tree_structure_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_structure
|
||||
'127.0.0.1':
|
||||
- fail_structure
|
||||
"""
|
||||
state_file = """
|
||||
extend:
|
||||
Some file state:
|
||||
file:
|
||||
- name: /tmp/bar
|
||||
- contents: bar
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_structure.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def state_tree_run_fail(base_env_state_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_run
|
||||
'127.0.0.1':
|
||||
- fail_run
|
||||
"""
|
||||
state_file = """
|
||||
This file state fails:
|
||||
file.managed:
|
||||
- name: /tmp/non/ex/is/tent
|
||||
- makedirs: false
|
||||
- contents: foo
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
state_tempfile = pytest.helpers.temp_file(
|
||||
"fail_run.sls", state_file, base_env_state_tree_root_dir
|
||||
)
|
||||
with top_tempfile, state_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def pillar_tree_render_fail(base_env_pillar_tree_root_dir):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- fail_render
|
||||
'127.0.0.1':
|
||||
- fail_render
|
||||
"""
|
||||
pillar_file = r"""
|
||||
not_defined: {{ abc }}
|
||||
"""
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_pillar_tree_root_dir
|
||||
)
|
||||
pillar_tempfile = pytest.helpers.temp_file(
|
||||
"fail_render.sls", pillar_file, base_env_pillar_tree_root_dir
|
||||
)
|
||||
with top_tempfile, pillar_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
def test_state_with_import(salt_ssh_cli, state_tree):
|
||||
"""
|
||||
verify salt-ssh can use imported map files in states
|
||||
"""
|
||||
ret = salt_ssh_cli.run("state.sls", "test")
|
||||
assert ret.returncode == 0
|
||||
assert ret.data
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"ssh_cmd",
|
||||
[
|
||||
"state.sls",
|
||||
"state.highstate",
|
||||
"state.apply",
|
||||
"state.show_top",
|
||||
"state.show_highstate",
|
||||
"state.show_low_sls",
|
||||
"state.show_lowstate",
|
||||
"state.sls_id",
|
||||
"state.show_sls",
|
||||
"state.top",
|
||||
],
|
||||
)
|
||||
@pytest.mark.slow_test
|
||||
def test_state_with_import_dir(salt_ssh_cli, state_tree_dir, ssh_cmd):
|
||||
"""
|
||||
verify salt-ssh can use imported map files in states
|
||||
when the map files are in another directory outside of
|
||||
sls files importing them.
|
||||
"""
|
||||
if ssh_cmd in ("state.sls", "state.show_low_sls", "state.show_sls"):
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "test")
|
||||
elif ssh_cmd == "state.top":
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "top.sls")
|
||||
elif ssh_cmd == "state.sls_id":
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "Ok with def", "test")
|
||||
else:
|
||||
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd)
|
||||
assert ret.returncode == 0
|
||||
if ssh_cmd == "state.show_top":
|
||||
assert ret.data == {"base": ["test", "master_tops_test"]} or {"base": ["test"]}
|
||||
elif ssh_cmd in ("state.show_highstate", "state.show_sls"):
|
||||
assert ret.data == {
|
||||
"Ok with def": {
|
||||
"__sls__": "test",
|
||||
"__env__": "base",
|
||||
"test": ["succeed_without_changes", {"order": 10000}],
|
||||
}
|
||||
}
|
||||
elif ssh_cmd in ("state.show_low_sls", "state.show_lowstate", "state.show_sls"):
|
||||
assert ret.data == [
|
||||
{
|
||||
"state": "test",
|
||||
"name": "Ok with def",
|
||||
"__sls__": "test",
|
||||
"__env__": "base",
|
||||
"__id__": "Ok with def",
|
||||
"order": 10000,
|
||||
"fun": "succeed_without_changes",
|
||||
}
|
||||
]
|
||||
else:
|
||||
assert ret.data["test_|-Ok with def_|-Ok with def_|-succeed_without_changes"][
|
||||
"result"
|
||||
]
|
||||
assert ret.data
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def nested_state_tree(base_env_state_tree_root_dir, tmp_path):
|
||||
top_file = """
|
||||
base:
|
||||
'localhost':
|
||||
- basic
|
||||
'127.0.0.1':
|
||||
- basic
|
||||
"""
|
||||
state_file = """
|
||||
/{}/file.txt:
|
||||
file.managed:
|
||||
- source: salt://foo/file.jinja
|
||||
- template: jinja
|
||||
""".format(
|
||||
tmp_path
|
||||
)
|
||||
file_jinja = """
|
||||
{% from 'foo/map.jinja' import comment %}{{ comment }}
|
||||
"""
|
||||
map_file = """
|
||||
{% set comment = "blah blah" %}
|
||||
"""
|
||||
statedir = base_env_state_tree_root_dir / "foo"
|
||||
top_tempfile = pytest.helpers.temp_file(
|
||||
"top.sls", top_file, base_env_state_tree_root_dir
|
||||
)
|
||||
map_tempfile = pytest.helpers.temp_file("map.jinja", map_file, statedir)
|
||||
file_tempfile = pytest.helpers.temp_file("file.jinja", file_jinja, statedir)
|
||||
state_tempfile = pytest.helpers.temp_file("init.sls", state_file, statedir)
|
||||
|
||||
with top_tempfile, map_tempfile, state_tempfile, file_tempfile:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
def test_state_with_import_from_dir(salt_ssh_cli, nested_state_tree):
|
||||
"""
|
||||
verify salt-ssh can use imported map files in states
|
||||
"""
|
||||
ret = salt_ssh_cli.run(
|
||||
"--extra-filerefs=salt://foo/map.jinja", "state.apply", "foo"
|
||||
)
|
||||
assert ret.returncode == 0
|
||||
assert ret.data
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
def test_state_low(salt_ssh_cli):
|
||||
"""
|
||||
test state.low with salt-ssh
|
||||
"""
|
||||
ret = salt_ssh_cli.run(
|
||||
"state.low", '{"state": "cmd", "fun": "run", "name": "echo blah"}'
|
||||
)
|
||||
assert (
|
||||
json.loads(ret.stdout)["localhost"]["cmd_|-echo blah_|-echo blah_|-run"][
|
||||
"changes"
|
||||
]["stdout"]
|
||||
== "blah"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
def test_state_high(salt_ssh_cli):
|
||||
"""
|
||||
test state.high with salt-ssh
|
||||
"""
|
||||
ret = salt_ssh_cli.run("state.high", '{"echo blah": {"cmd": ["run"]}}')
|
||||
assert (
|
||||
json.loads(ret.stdout)["localhost"]["cmd_|-echo blah_|-echo blah_|-run"][
|
||||
"changes"
|
||||
]["stdout"]
|
||||
== "blah"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
@pytest.mark.usefixtures("state_tree_render_fail")
|
||||
class TestRenderExceptionRetcode:
|
||||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a state rendering fails.
|
||||
"""
|
||||
|
||||
def test_retcode_state_sls_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls", "fail_render")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_highstate_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.highstate")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_sls_id_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls_id", "foo", "fail_render")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_sls_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_sls", "fail_render")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_low_sls_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_low_sls", "fail_render")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_highstate_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_highstate")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_lowstate_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_lowstate")
|
||||
# state.show_lowstate exits with 0 for non-ssh as well
|
||||
self._assert_ret(ret, 0)
|
||||
|
||||
def test_retcode_state_top_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.top", "top.sls")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_single_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.single", "file")
|
||||
assert ret.returncode == EX_AGGREGATE
|
||||
assert isinstance(ret.data, str)
|
||||
assert "single() missing 1 required positional argument" in ret.data
|
||||
|
||||
def _assert_ret(self, ret, retcode):
|
||||
assert ret.returncode == retcode
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0].startswith(
|
||||
"Rendering SLS 'base:fail_render' failed: Jinja variable 'abc' is undefined;"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
@pytest.mark.usefixtures("pillar_tree_render_fail")
|
||||
class TestPillarRenderExceptionRetcode:
|
||||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a pillar rendering fails.
|
||||
"""
|
||||
|
||||
def test_retcode_state_sls_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls", "basic")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def test_retcode_state_highstate_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.highstate")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def test_retcode_state_sls_id_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls_id", "foo", "basic")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def test_retcode_state_show_sls_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_sls", "basic")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def test_retcode_state_show_low_sls_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_low_sls", "basic")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def test_retcode_state_show_highstate_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_highstate")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def test_retcode_state_show_lowstate_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_lowstate")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def test_retcode_state_top_pillar_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.top", "top.sls")
|
||||
self._assert_ret(ret)
|
||||
|
||||
def _assert_ret(self, ret):
|
||||
assert ret.returncode == EX_AGGREGATE
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0] == "Pillar failed to render with the following messages:"
|
||||
assert ret.data[1].startswith("Rendering SLS 'fail_render' failed.")
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
@pytest.mark.usefixtures("state_tree_req_fail")
|
||||
class TestStateReqFailRetcode:
|
||||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a highstate verification fails.
|
||||
``state.show_highstate`` does not validate this.
|
||||
"""
|
||||
|
||||
def test_retcode_state_sls_invalid_requisite(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls", "fail_req")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_highstate_invalid_requisite(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.highstate")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_sls_invalid_requisite(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_sls", "fail_req")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_low_sls_invalid_requisite(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_low_sls", "fail_req")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_lowstate_invalid_requisite(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_lowstate")
|
||||
# state.show_lowstate exits with 0 for non-ssh as well
|
||||
self._assert_ret(ret, 0)
|
||||
|
||||
def test_retcode_state_top_invalid_requisite(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.top", "top.sls")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def _assert_ret(self, ret, retcode):
|
||||
assert ret.returncode == retcode
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0].startswith(
|
||||
"Invalid requisite in require: file.managed for invalid_requisite"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
@pytest.mark.usefixtures("state_tree_structure_fail")
|
||||
class TestStateStructureFailRetcode:
|
||||
"""
|
||||
Verify salt-ssh fails with a retcode > 0 when a highstate verification fails.
|
||||
This targets another step of the verification.
|
||||
``state.sls_id`` does not seem to support extends.
|
||||
``state.show_highstate`` does not validate this.
|
||||
"""
|
||||
|
||||
def test_retcode_state_sls_invalid_structure(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls", "fail_structure")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_highstate_invalid_structure(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.highstate")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_sls_invalid_structure(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_sls", "fail_structure")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_low_sls_invalid_structure(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_low_sls", "fail_structure")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def test_retcode_state_show_lowstate_invalid_structure(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.show_lowstate")
|
||||
# state.show_lowstate exits with 0 for non-ssh as well
|
||||
self._assert_ret(ret, 0)
|
||||
|
||||
def test_retcode_state_top_invalid_structure(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.top", "top.sls")
|
||||
self._assert_ret(ret, EX_AGGREGATE)
|
||||
|
||||
def _assert_ret(self, ret, retcode):
|
||||
assert ret.returncode == retcode
|
||||
assert isinstance(ret.data, list)
|
||||
assert ret.data
|
||||
assert isinstance(ret.data[0], str)
|
||||
assert ret.data[0].startswith(
|
||||
"Cannot extend ID 'Some file state' in 'base:fail_structure"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.slow_test
|
||||
@pytest.mark.usefixtures("state_tree_run_fail")
|
||||
class TestStateRunFailRetcode:
|
||||
"""
|
||||
Verify salt-ssh passes on a failing retcode from state execution.
|
||||
"""
|
||||
|
||||
def test_retcode_state_sls_run_fail(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls", "fail_run")
|
||||
assert ret.returncode == EX_AGGREGATE
|
||||
|
||||
def test_retcode_state_highstate_run_fail(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.highstate")
|
||||
assert ret.returncode == EX_AGGREGATE
|
||||
|
||||
def test_retcode_state_sls_id_render_exception(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.sls_id", "This file state fails", "fail_run")
|
||||
assert ret.returncode == EX_AGGREGATE
|
||||
|
||||
def test_retcode_state_top_run_fail(self, salt_ssh_cli):
|
||||
ret = salt_ssh_cli.run("state.top", "top.sls")
|
||||
assert ret.returncode == EX_AGGREGATE
|
|
@ -1,11 +1,3 @@
|
|||
"""
|
||||
:synopsis: Unit Tests for Advanced Packaging Tool module 'module.aptpkg'
|
||||
:platform: Linux
|
||||
:maturity: develop
|
||||
versionadded:: 2017.7.0
|
||||
"""
|
||||
|
||||
|
||||
import copy
|
||||
import importlib
|
||||
import logging
|
||||
|
@ -24,7 +16,7 @@ from salt.exceptions import (
|
|||
SaltInvocationError,
|
||||
)
|
||||
from salt.utils.odict import OrderedDict
|
||||
from tests.support.mock import MagicMock, Mock, call, mock_open, patch
|
||||
from tests.support.mock import MagicMock, Mock, call, patch
|
||||
|
||||
try:
|
||||
from aptsources.sourceslist import ( # pylint: disable=unused-import
|
||||
|
@ -1556,31 +1548,35 @@ SERVICE:cups-daemon,390,/usr/sbin/cupsd
|
|||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _test_sourceslist_multiple_comps_fs(fs):
|
||||
fs.create_dir("/etc/apt/sources.list.d")
|
||||
fs.create_file(
|
||||
"/etc/apt/sources.list",
|
||||
contents="deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted",
|
||||
)
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
HAS_APTSOURCES is True, reason="Only run test with python3-apt library is missing."
|
||||
)
|
||||
@pytest.mark.usefixtures("_test_sourceslist_multiple_comps_fs")
|
||||
def test_sourceslist_multiple_comps():
|
||||
"""
|
||||
Test SourcesList when repo has multiple comps
|
||||
"""
|
||||
repo_line = "deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted"
|
||||
with patch.object(aptpkg, "HAS_APT", return_value=True):
|
||||
with patch("salt.utils.files.fopen", mock_open(read_data=repo_line)):
|
||||
with patch("pathlib.Path.is_file", side_effect=[True, False]):
|
||||
sources = aptpkg.SourcesList()
|
||||
for source in sources:
|
||||
assert source.type == "deb"
|
||||
assert source.uri == "http://archive.ubuntu.com/ubuntu/"
|
||||
assert source.comps == ["main", "restricted"]
|
||||
assert source.dist == "focal-updates"
|
||||
sources = aptpkg.SourcesList()
|
||||
for source in sources:
|
||||
assert source.type == "deb"
|
||||
assert source.uri == "http://archive.ubuntu.com/ubuntu/"
|
||||
assert source.comps == ["main", "restricted"]
|
||||
assert source.dist == "focal-updates"
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
HAS_APTSOURCES is True, reason="Only run test with python3-apt library is missing."
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"repo_line",
|
||||
[
|
||||
@pytest.fixture(
|
||||
params=(
|
||||
"deb [ arch=amd64 ] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted",
|
||||
"deb [arch=amd64 ] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted",
|
||||
"deb [arch=amd64 test=one ] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted",
|
||||
|
@ -1588,24 +1584,31 @@ def test_sourceslist_multiple_comps():
|
|||
"deb [ arch=amd64,armel test=one ] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted",
|
||||
"deb [ arch=amd64,armel test=one] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted",
|
||||
"deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ focal-updates main restricted",
|
||||
],
|
||||
)
|
||||
)
|
||||
def repo_line(request, fs):
|
||||
fs.create_dir("/etc/apt/sources.list.d")
|
||||
fs.create_file("/etc/apt/sources.list", contents=request.param)
|
||||
yield request.param
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
HAS_APTSOURCES is True, reason="Only run test with python3-apt library is missing."
|
||||
)
|
||||
def test_sourceslist_architectures(repo_line):
|
||||
"""
|
||||
Test SourcesList when architectures is in repo
|
||||
"""
|
||||
with patch("salt.utils.files.fopen", mock_open(read_data=repo_line)):
|
||||
with patch("pathlib.Path.is_file", side_effect=[True, False]):
|
||||
sources = aptpkg.SourcesList()
|
||||
for source in sources:
|
||||
assert source.type == "deb"
|
||||
assert source.uri == "http://archive.ubuntu.com/ubuntu/"
|
||||
assert source.comps == ["main", "restricted"]
|
||||
assert source.dist == "focal-updates"
|
||||
if "," in repo_line:
|
||||
assert source.architectures == ["amd64", "armel"]
|
||||
else:
|
||||
assert source.architectures == ["amd64"]
|
||||
sources = aptpkg.SourcesList()
|
||||
for source in sources:
|
||||
assert source.type == "deb"
|
||||
assert source.uri == "http://archive.ubuntu.com/ubuntu/"
|
||||
assert source.comps == ["main", "restricted"]
|
||||
assert source.dist == "focal-updates"
|
||||
if "," in repo_line:
|
||||
assert source.architectures == ["amd64", "armel"]
|
||||
else:
|
||||
assert source.architectures == ["amd64"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
import logging
|
||||
|
||||
import msgpack
|
||||
import pytest
|
||||
|
||||
import salt.config
|
||||
import salt.transport.base
|
||||
import salt.transport.zeromq
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.core_test,
|
||||
]
|
||||
|
||||
|
||||
async def test_req_server_garbage_request(io_loop):
|
||||
"""
|
||||
|
|
Loading…
Add table
Reference in a new issue