train-pwsh 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +58 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.md +9 -0
- data/NOTICE.md +7 -0
- data/README.md +54 -0
- data/Rakefile +4 -0
- data/lib/train-pwsh/connection.rb +156 -0
- data/lib/train-pwsh/platform.rb +38 -0
- data/lib/train-pwsh/transport.rb +38 -0
- data/lib/train-pwsh/version.rb +7 -0
- data/lib/train-pwsh.rb +21 -0
- data/sig/train/pwsh.rbs +6 -0
- data/train-pwsh.gemspec +43 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e116dd35ef28fabbaacb70352c42a8335d028949f7cd417418b2bce4b9bdd008
|
4
|
+
data.tar.gz: 23fe2e4625a8a8904899de5dada14a625e6e1aa1ee0ae627aa44a263e770ff2c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d44661cc9311e5f20cdedc53ef30706758945d3b96e7e5ca4814d0127a1c73cc340897de239f583a60a06108536acf59e328e801d6bc1fb09fa491c2bc7b045
|
7
|
+
data.tar.gz: 6f8dc2b638115c43d20a967a653081ecd4927910f3d5dceac8d9836137c060fa73950b86c90fab478113f667a1220132144c80aaf6fa74db7883a9c104490428
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- "libraries/**/*"
|
4
|
+
|
5
|
+
Layout/LineLength:
|
6
|
+
Max: 1500
|
7
|
+
AllowURI: true
|
8
|
+
IgnoreCopDirectives: true
|
9
|
+
|
10
|
+
Naming/FileName:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Metrics/BlockLength:
|
14
|
+
Max: 1000
|
15
|
+
|
16
|
+
Lint/ConstantDefinitionInBlock:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
# Required for Profiles as it can introduce profile errors
|
20
|
+
Style/NumericPredicate:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/WordArray:
|
24
|
+
Description: "Use %w or %W for an array of words. (https://rubystyle.guide#percent-w)"
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Style/RedundantPercentQ:
|
28
|
+
Enabled: true
|
29
|
+
|
30
|
+
Style/NestedParenthesizedCalls:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Style/TrailingCommaInHashLiteral:
|
34
|
+
Description: "https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral"
|
35
|
+
Enabled: true
|
36
|
+
EnforcedStyleForMultiline: no_comma
|
37
|
+
|
38
|
+
Style/TrailingCommaInArrayLiteral:
|
39
|
+
Enabled: true
|
40
|
+
EnforcedStyleForMultiline: no_comma
|
41
|
+
|
42
|
+
Style/BlockDelimiters:
|
43
|
+
Enabled: false
|
44
|
+
|
45
|
+
Lint/AmbiguousBlockAssociation:
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
Metrics/BlockNesting:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
Lint/ShadowingOuterLocalVariable:
|
52
|
+
Enabled: false
|
53
|
+
|
54
|
+
Style/FormatStringToken:
|
55
|
+
Enabled: false
|
56
|
+
|
57
|
+
Style/FrozenStringLiteralComment:
|
58
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
6
|
+
|
7
|
+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
8
|
+
|
9
|
+
## Our Standards
|
10
|
+
|
11
|
+
Examples of behavior that contributes to a positive environment for our community include:
|
12
|
+
|
13
|
+
* Demonstrating empathy and kindness toward other people
|
14
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
15
|
+
* Giving and gracefully accepting constructive feedback
|
16
|
+
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
17
|
+
* Focusing on what is best not just for us as individuals, but for the overall community
|
18
|
+
|
19
|
+
Examples of unacceptable behavior include:
|
20
|
+
|
21
|
+
* The use of sexualized language or imagery, and sexual attention or
|
22
|
+
advances of any kind
|
23
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
24
|
+
* Public or private harassment
|
25
|
+
* Publishing others' private information, such as a physical or email
|
26
|
+
address, without their explicit permission
|
27
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
28
|
+
professional setting
|
29
|
+
|
30
|
+
## Enforcement Responsibilities
|
31
|
+
|
32
|
+
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
33
|
+
|
34
|
+
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
|
35
|
+
|
36
|
+
## Scope
|
37
|
+
|
38
|
+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
39
|
+
|
40
|
+
## Enforcement
|
41
|
+
|
42
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at skandwal@mitre.org. All complaints will be reviewed and investigated promptly and fairly.
|
43
|
+
|
44
|
+
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
45
|
+
|
46
|
+
## Enforcement Guidelines
|
47
|
+
|
48
|
+
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
49
|
+
|
50
|
+
### 1. Correction
|
51
|
+
|
52
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
|
53
|
+
|
54
|
+
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
|
55
|
+
|
56
|
+
### 2. Warning
|
57
|
+
|
58
|
+
**Community Impact**: A violation through a single incident or series of actions.
|
59
|
+
|
60
|
+
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
|
61
|
+
|
62
|
+
### 3. Temporary Ban
|
63
|
+
|
64
|
+
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
|
65
|
+
|
66
|
+
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
67
|
+
|
68
|
+
### 4. Permanent Ban
|
69
|
+
|
70
|
+
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
71
|
+
|
72
|
+
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
73
|
+
|
74
|
+
## Attribution
|
75
|
+
|
76
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
|
77
|
+
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
78
|
+
|
79
|
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
80
|
+
|
81
|
+
[homepage]: https://www.contributor-covenant.org
|
82
|
+
|
83
|
+
For answers to common questions about this code of conduct, see the FAQ at
|
84
|
+
https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
|
data/LICENSE.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Licensed under the apache-2.0 license, except as noted below.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
4
|
+
|
5
|
+
* Redistributions of source code must retain the above copyright/ digital rights legend, this list of conditions and the following Notice.
|
6
|
+
|
7
|
+
* Redistributions in binary form must reproduce the above copyright copyright/ digital rights legend, this list of conditions and the following Notice in the documentation and/or other materials provided with the distribution.
|
8
|
+
|
9
|
+
* Neither the name of The MITRE Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
data/NOTICE.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# NOTICE
|
2
|
+
|
3
|
+
MITRE grants permission to reproduce, distribute, modify, and otherwise use this software to the extent permitted by the licensed terms provided in the LICENSE.md file included with this project.
|
4
|
+
|
5
|
+
This software was produced by The MITRE Corporation for the U. S. Government under contract. As such the U.S. Government has certain use and data rights in this software. No use other than those granted to the U. S. Government, or to those acting on behalf of the U. S. Government, under these contract arrangements is authorized without the express written permission of The MITRE Corporation.
|
6
|
+
|
7
|
+
For further information, please contact The MITRE Corporation, Contracts Management Office, 7515 Colshire Drive, McLean, VA 22102-7539, (703) 983-6000.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Train::Pwsh
|
2
|
+
|
3
|
+
A train-pwsh connection has 7 fields that are needed for authentication, which are listed below:
|
4
|
+
- client_id
|
5
|
+
- tenant_id
|
6
|
+
- client_secret
|
7
|
+
- certificate_path
|
8
|
+
- certificate_password
|
9
|
+
- organization
|
10
|
+
- sharepoint_admin_url
|
11
|
+
|
12
|
+
These fields need to be defined in the config file stored at this directory: `~/.inspec/config.json`. Particularly, under the `credentials` key of the json file, create a `pwsh` key with the value being another dictionary. This dictionary should have a key named `pwsh-options` with the value being another dictionary. This dictionary should contain the names of the seven fields above as well as their values. Please refer to this [link](https://origin.inspec.io/docs/reference/config/) for more detailed instructions.
|
13
|
+
|
14
|
+
Alternatively, if train is being invoked using code, this is how it can be used:
|
15
|
+
|
16
|
+
**Pwsh**
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require 'train'
|
20
|
+
train = Train.create('pwsh',
|
21
|
+
client_id: '1', tenant_id: '2', client_secret: '3', certificate_path: '4', certificate_password: '5', organization: '6', sharepoint_admin_url: '7')
|
22
|
+
```
|
23
|
+
|
24
|
+
## Installation
|
25
|
+
|
26
|
+
Install the gem and add to the application's Gemfile by executing:
|
27
|
+
|
28
|
+
$ bundle add train-pwsh
|
29
|
+
|
30
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
31
|
+
|
32
|
+
$ gem install train-pwsh
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
Train-pwsh should be used alongside inspec-pwsh, which is a resource pack that is used by profiles to help maintain persisten sessions for the different modules that are called Powershell-based profiles.
|
37
|
+
|
38
|
+
Please refer to the following link for [inspec-pwsh documentation](https://github.com/mitre/inspec-pwsh)
|
39
|
+
|
40
|
+
To test if train-pwsh and inspec-pwsh is working correctly on your system, try running the `o365_example_baseline` profile and check the results. If it runs correctly based on your Microsoft 365 configurations, then train-pwsh and inspec-pwsh are properly set.
|
41
|
+
|
42
|
+
Please refer to the following link for [o365_example_baseline documentation](https://github.com/mitre/o365_example_baseline)
|
43
|
+
|
44
|
+
## Contributing
|
45
|
+
|
46
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/train-pwsh. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/train-pwsh/blob/main/CODE_OF_CONDUCT.md).
|
47
|
+
|
48
|
+
## License
|
49
|
+
|
50
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
51
|
+
|
52
|
+
## Code of Conduct
|
53
|
+
|
54
|
+
Everyone interacting in the Train::Pwsh project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/train-pwsh/blob/main/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
# Connection definition file for an example Train plugin.
|
2
|
+
|
3
|
+
# Most of the work of a Train plugin happens in this file.
|
4
|
+
# Connections derive from Train::Plugins::Transport::BaseConnection,
|
5
|
+
# and provide a variety of services. Later generations of the plugin
|
6
|
+
# API will likely separate out these responsibilities, but for now,
|
7
|
+
# some of the responsibilities include:
|
8
|
+
# * authentication to the target
|
9
|
+
# * platform / release /family detection
|
10
|
+
# * caching
|
11
|
+
# * filesystem access
|
12
|
+
# * remote command execution
|
13
|
+
# * API execution
|
14
|
+
# * marshalling to / from JSON
|
15
|
+
# You don't have to worry about most of this.
|
16
|
+
|
17
|
+
# This allow us to inherit from Train::Plugins::Transport::BaseConnection
|
18
|
+
require "train"
|
19
|
+
|
20
|
+
# Push platform detection out to a mixin, as it tends
|
21
|
+
# to develop at a different cadence than the rest
|
22
|
+
require "train-pwsh/platform"
|
23
|
+
|
24
|
+
# This is a support library for our file content meddling
|
25
|
+
# require "train-pwsh/file_content_rotator"
|
26
|
+
|
27
|
+
# This is a support library for our holding powershell session
|
28
|
+
require "ruby-pwsh"
|
29
|
+
|
30
|
+
module TrainPlugins
|
31
|
+
module Pwsh
|
32
|
+
# You must inherit from BaseConnection.
|
33
|
+
class Connection < Train::Plugins::Transport::BaseConnection
|
34
|
+
# We've placed platform detection in a separate module; pull it in here.
|
35
|
+
include TrainPlugins::Pwsh::Platform
|
36
|
+
|
37
|
+
def initialize(options)
|
38
|
+
# 'options' here is a hash, Symbol-keyed,
|
39
|
+
# of what Train.target_config decided to do with the URI that it was
|
40
|
+
# passed by `inspec -t` (or however the application gathered target information)
|
41
|
+
# Some plugins might use this moment to capture credentials from the URI,
|
42
|
+
# and the configure an underlying SDK accordingly.
|
43
|
+
# You might also take a moment to manipulate the options.
|
44
|
+
# Have a look at the Local, SSH, and AWS transports for ideas about what
|
45
|
+
# you can do with the options.
|
46
|
+
|
47
|
+
# Regardless, let the BaseConnection have a chance to configure itself.
|
48
|
+
super(options)
|
49
|
+
puts('Please wait a few minutes to let the Powershell modules download and connection get established... ')
|
50
|
+
#Instance variables that store the necessary authentication credentials
|
51
|
+
#@pwsh_session_graph_exchange = ::Pwsh::Manager.instance('/opt/homebrew/bin/pwsh', ['-NoLogo'])
|
52
|
+
#@pwsh_session_teams_pnp = ::Pwsh::Manager.instance('/opt/homebrew/bin/pwsh', [])
|
53
|
+
@pwsh_session_graph_exchange = @options.delete(:graph_exchange_session)
|
54
|
+
@pwsh_session_teams_pnp = @options.delete(:teams_pnp_session)
|
55
|
+
@client_id = @options.delete(:client_id)
|
56
|
+
@tenant_id = @options.delete(:tenant_id)
|
57
|
+
@client_secret = @options.delete(:client_secret)
|
58
|
+
@certificate_path = @options.delete(:certificate_path)
|
59
|
+
@certificate_password = @options.delete(:certificate_password)
|
60
|
+
@organization = @options.delete(:organization)
|
61
|
+
@sharepoint_admin_url = @options.delete(:sharepoint_admin_url)
|
62
|
+
|
63
|
+
exit_status_graph_exchange = install_connect_graph_exchange()
|
64
|
+
exit_status_teams_pnp = install_connect_teams_pnp()
|
65
|
+
if exit_status_graph_exchange != 0
|
66
|
+
return exit_status_graph_exchange
|
67
|
+
elsif exit_status_teams_pnp != 0
|
68
|
+
return exit_status_teams_pnp
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
def file_via_connection(path)
|
74
|
+
return Train::File::Local::Windows.new(self,path)
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_command_via_connection(script, session_type_hash)
|
78
|
+
if session_type_hash.key?(:graph_exchange_session)
|
79
|
+
return run_script_in_graph_exchange(script)
|
80
|
+
elsif session_type_hash.key?(:teams_pnp_session)
|
81
|
+
return run_script_in_teams_pnp(script)
|
82
|
+
else
|
83
|
+
return CommandResult.new("","",0)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
#Establishes connection for modules such as mggraph, exchangeonline
|
87
|
+
def install_connect_graph_exchange()
|
88
|
+
pwsh_graph_exchange_install_connect = %{
|
89
|
+
#Collect designated inputs required for Graph and Exchange connections
|
90
|
+
$client_id = '#{@client_id}'
|
91
|
+
$tenantid = '#{@tenant_id}'
|
92
|
+
$clientSecret = '#{@client_secret}'
|
93
|
+
$certificate_password = '#{@certificate_password}'
|
94
|
+
$certificate_path = '#{@certificate_path}'
|
95
|
+
$organization = '#{@organization}'
|
96
|
+
|
97
|
+
#Connect to Graph module
|
98
|
+
If($null -eq (get-module -listavailable -name "microsoft.graph")){install-module microsoft.graph}
|
99
|
+
If($null -eq (get-module -name "microsoft.graph")){import-module microsoft.graph}
|
100
|
+
$password = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force
|
101
|
+
$ClientSecretCredential = New-Object -TypeName System.Management.Automation.PSCredential($client_id,$password)
|
102
|
+
Connect-MgGraph -TenantId $tenantid -ClientSecretCredential $ClientSecretCredential -NoWelcome
|
103
|
+
|
104
|
+
#Connect to Exchange module
|
105
|
+
If($null -eq (get-module -listavailable -name "ExchangeOnlineManagement")){install-module ExchangeOnlineManagement}
|
106
|
+
If($null -eq (get-module -name "ExchangeOnlineManagement")){import-module ExchangeOnlineManagement}
|
107
|
+
$password = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force
|
108
|
+
$ClientSecretCredential = New-Object -TypeName System.Management.Automation.PSCredential($client_id,$password)
|
109
|
+
Connect-ExchangeOnline -CertificateFilePath $certificate_path -CertificatePassword (ConvertTo-SecureString -String $certificate_password -AsPlainText -Force) -AppID $client_id -Organization $organization -ShowBanner:$false
|
110
|
+
}
|
111
|
+
|
112
|
+
pwsh_graph_exchange_install_connect_result = @pwsh_session_graph_exchange.execute(pwsh_graph_exchange_install_connect)
|
113
|
+
return pwsh_graph_exchange_install_connect_result[:exitcode]
|
114
|
+
end
|
115
|
+
|
116
|
+
def uri
|
117
|
+
return 'pwsh://'
|
118
|
+
end
|
119
|
+
|
120
|
+
def install_connect_teams_pnp()
|
121
|
+
pwsh_teams_pnp_install_connect = %{
|
122
|
+
#Collect designated inputs required for Graph, Exchange, and PnP connections
|
123
|
+
$client_id = '#{@client_id}'
|
124
|
+
$tenantid = '#{@tenant_id}'
|
125
|
+
$certificate_password = '#{@certificate_password}'
|
126
|
+
$certificate_path = '#{@certificate_path}'
|
127
|
+
$sharepoint_admin_url = '#{@sharepoint_admin_url}'
|
128
|
+
|
129
|
+
#Connect to Teams module
|
130
|
+
If($null -eq (get-module -listavailable -name "MicrosoftTeams")){install-module MicrosoftTeams}
|
131
|
+
If($null -eq (get-module -name "MicrosoftTeams")){import-module MicrosoftTeams}
|
132
|
+
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certificate_path,$certificate_password)
|
133
|
+
Connect-MicrosoftTeams -Certificate $cert -ApplicationId $client_id -TenantId $tenantid > $null
|
134
|
+
|
135
|
+
#Connect to PnP module
|
136
|
+
If($null -eq (get-module -listavailable -name "PnP.PowerShell")){install-module PnP.PowerShell}
|
137
|
+
If($null -eq (get-module -name "PnP.PowerShell")){import-module PnP.PowerShell}
|
138
|
+
$password = (ConvertTo-SecureString -AsPlainText $certificate_password -Force)
|
139
|
+
Connect-PnPOnline -Url $sharepoint_admin_url -ClientId $client_id -CertificatePath $certificate_path -CertificatePassword $password -Tenant $tenantid
|
140
|
+
}
|
141
|
+
pwsh_teams_pnp_install_connect_result = @pwsh_session_teams_pnp.execute(pwsh_teams_pnp_install_connect)
|
142
|
+
return pwsh_teams_pnp_install_connect_result[:exitcode]
|
143
|
+
end
|
144
|
+
|
145
|
+
def run_script_in_graph_exchange(script)
|
146
|
+
result = @pwsh_session_graph_exchange.execute(script)
|
147
|
+
return CommandResult.new(result[:stdout],result[:stderr],result[:exitcode])
|
148
|
+
end
|
149
|
+
|
150
|
+
def run_script_in_teams_pnp(script)
|
151
|
+
result = @pwsh_session_teams_pnp.execute(script)
|
152
|
+
return CommandResult.new(result[:stdout],result[:stderr],result[:exitcode])
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Platform definition file. This is a good place to separate out any
|
2
|
+
# logic regarding the identification of the OS or API at the far end
|
3
|
+
# of the connection.
|
4
|
+
require 'ruby-pwsh'
|
5
|
+
# Abbreviate the namespace here, if you like.
|
6
|
+
module TrainPlugins::Pwsh
|
7
|
+
# Since we're mixing in the platform detection facility into Connection,
|
8
|
+
# this has to come in as a Module.
|
9
|
+
module Platform
|
10
|
+
# The method `platform` is called when platform detection is
|
11
|
+
# about to be performed. Train core defines a sophisticated
|
12
|
+
# system for platform detection, but for most plugins, you'll
|
13
|
+
# only ever run on the special platform for which you are targeting.
|
14
|
+
def platform
|
15
|
+
# If you are declaring a new platform, you will need to tell
|
16
|
+
# Train a bit about it.
|
17
|
+
# If you were defining a cloud API, you should say you are a member
|
18
|
+
# of the cloud family.
|
19
|
+
|
20
|
+
# This plugin makes up a new platform. Train (or rather InSpec) only
|
21
|
+
# know how to read files on Windows and Un*x (MacOS is a kind of Un*x),
|
22
|
+
# so we'll say we're part of those families.
|
23
|
+
Train::Platforms.name("pwsh").in_family("unix")
|
24
|
+
Train::Platforms.name("pwsh").in_family("windows")
|
25
|
+
|
26
|
+
# When you know you will only ever run on your dedicated platform
|
27
|
+
# (for example, a plugin named train-aws would only run on the AWS
|
28
|
+
# API, which we report as the 'aws' platform).
|
29
|
+
# force_platform! lets you bypass platform detection.
|
30
|
+
# The options to this are not currently documented completely.
|
31
|
+
|
32
|
+
# Use release to report a version number. You might use the version
|
33
|
+
# of the plugin, or a version of an important underlying SDK, or a
|
34
|
+
# version of a remote API.
|
35
|
+
force_platform!("pwsh", release: Train::Pwsh::VERSION)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Train Plugins v1 are usually declared under the TrainPlugins namespace.
|
2
|
+
# Each plugin has three components: Transport, Connection, and Platform.
|
3
|
+
# We'll only define the Transport here, but we'll refer to the others.
|
4
|
+
require "train-pwsh/connection"
|
5
|
+
require "ruby-pwsh"
|
6
|
+
module TrainPlugins
|
7
|
+
module Pwsh
|
8
|
+
class Transport < Train.plugin(1)
|
9
|
+
name "pwsh"
|
10
|
+
|
11
|
+
# The only thing you MUST do in a transport is a define a
|
12
|
+
# connection() method that returns a instance that is a
|
13
|
+
# subclass of BaseConnection.
|
14
|
+
# Required fields in order for connection to be valid
|
15
|
+
|
16
|
+
#option :client_id, required: true, default: proc { ENV['CLIENT_ID'] } unless ENV['CLIENT_ID'].empty?
|
17
|
+
#option :tenant_id, required: true, default: proc { ENV['TENANT_ID'] } unless ENV['TENANT_ID'].empty?
|
18
|
+
#option :client_secret, required: true, default: proc { ENV['CLIENT_SECRET'] } unless ENV['CLIENT_SECRET'].empty?
|
19
|
+
#option :certificate_path, required: true, default: proc { ENV['CERTIFICATE_PATH'] } unless ENV['CERTIFICATE_PATH'].empty?
|
20
|
+
#option :certificate_password, required: true, default: proc { ENV['CERTIFICATE_PASSWORD'] } unless ENV['CERTIFICATE_PASSWORD'].empty?
|
21
|
+
#option :organization, required: true, default: proc { ENV['ORGANIZATION'] } unless ENV['ORGANIZATION'].empty?
|
22
|
+
#option :sharepoint_admin_url, required: true, default: proc { ENV['SHAREPOINT_ADMIN_URL'] } unless ENV['SHAREPOINT_ADMIN_URL'].empty?
|
23
|
+
|
24
|
+
option :graph_exchange_session, required: true, default: proc { ::Pwsh::Manager.instance(ENV['PWSH_PATH'], ['-NoLogo']) }
|
25
|
+
option :teams_pnp_session, required: true, default: proc { ::Pwsh::Manager.instance(ENV['PWSH_PATH'], []) }
|
26
|
+
|
27
|
+
# The options passed to this are undocumented and rarely used.
|
28
|
+
def connection(_instance_opts = nil)
|
29
|
+
# Typical practice is to cache the connection as an instance variable.
|
30
|
+
# Do what makes sense for your platform.
|
31
|
+
# @options here is the parsed options that the calling
|
32
|
+
# app handed to us at process invocation. See the Connection class
|
33
|
+
# for more details.
|
34
|
+
@connection ||= TrainPlugins::Pwsh::Connection.new(@options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/train-pwsh.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# This file is known as the "entry point."
|
2
|
+
# This is the file Train will try to load if it
|
3
|
+
# thinks your plugin is needed.
|
4
|
+
|
5
|
+
# The *only* thing this file should do is setup the
|
6
|
+
# load path, then load plugin files.
|
7
|
+
|
8
|
+
# Next two lines simply add the path of the gem to the load path.
|
9
|
+
# This is not needed when being loaded as a gem; but when doing
|
10
|
+
# plugin development, you may need it. Either way, it's harmless.
|
11
|
+
libdir = __dir__
|
12
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
13
|
+
|
14
|
+
# It's traditional to keep your gem version in a separate file, so CI can find it easier.
|
15
|
+
require "train-pwsh/version"
|
16
|
+
|
17
|
+
# A train plugin has three components: Transport, Connection, and Platform.
|
18
|
+
# Transport acts as the glue.
|
19
|
+
require "train-pwsh/transport"
|
20
|
+
require "train-pwsh/platform"
|
21
|
+
require "train-pwsh/connection"
|
data/sig/train/pwsh.rbs
ADDED
data/train-pwsh.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/train-pwsh/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "train-pwsh"
|
7
|
+
spec.version = Train::Pwsh::VERSION
|
8
|
+
spec.authors = ["Sujay Kandwal"]
|
9
|
+
spec.email = ["skandwal@mitre.org"]
|
10
|
+
spec.files = Dir['lib/**/*.rb'] + Dir['bin/*']+ ["README.md", "LICENSE.md", "NOTICE.md", "CHANGELOG.md", "CODE_OF_CONDUCT.md"]
|
11
|
+
spec.summary = "Enabling continuous Powershell connection over Inspec"
|
12
|
+
#spec.description = "TODO: Write a longer description or delete this line."
|
13
|
+
#spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 2.6.0"
|
16
|
+
|
17
|
+
#spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
18
|
+
|
19
|
+
#spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
#spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
21
|
+
#spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(__dir__) do
|
26
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
27
|
+
(File.expand_path(f) == __FILE__) ||
|
28
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git appveyor Gemfile])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
spec.bindir = "exe"
|
32
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ["lib"]
|
34
|
+
|
35
|
+
# Uncomment to register a new dependency of your gem
|
36
|
+
spec.add_dependency "train", "~> 3.10"
|
37
|
+
spec.add_dependency "ruby-pwsh"
|
38
|
+
#Add powershell dependency
|
39
|
+
#spec.add_dependency "pwsh" , "~> 0.1"
|
40
|
+
|
41
|
+
# For more information and examples about making a new gem, check out our
|
42
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: train-pwsh
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sujay Kandwal
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: train
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.10'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ruby-pwsh
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- skandwal@mitre.org
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".rubocop.yml"
|
49
|
+
- CHANGELOG.md
|
50
|
+
- CODE_OF_CONDUCT.md
|
51
|
+
- LICENSE.md
|
52
|
+
- NOTICE.md
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- lib/train-pwsh.rb
|
56
|
+
- lib/train-pwsh/connection.rb
|
57
|
+
- lib/train-pwsh/platform.rb
|
58
|
+
- lib/train-pwsh/transport.rb
|
59
|
+
- lib/train-pwsh/version.rb
|
60
|
+
- sig/train/pwsh.rbs
|
61
|
+
- train-pwsh.gemspec
|
62
|
+
homepage:
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.6.0
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubygems_version: 3.3.27
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: Enabling continuous Powershell connection over Inspec
|
85
|
+
test_files: []
|