Where should Puppet Resources be Placed? - windows

I have the following flyway.pp Puppet class which installs Flyway onto Windows machines. It copies two files into the installation folder.
class rehan::flyway {
package { 'flyway':
ensure => latest,
provider => chocolatey
}
file { 'C:/Program Files/flyway/ntlmauth.dll':
ensure => 'file',
source => 'puppet:///modules/rehan/manifests/ntlmauth.dll',
}
file { 'C:/Program Files/flyway/drivers/sqljdbc4.jar':
ensure => 'file',
source => 'puppet:///modules/rehan/manifests/sqljdbc4.jar',
}
}
The above modules lives at modules/rehan/manifests/flyway.pp. I have placed the two files ntlmauth.dll and sqljdbc4.jar along side it but it seems a bit messy. Is there a standard directory or location where these files are normally placed? Also, how can I refer to these files using a relative path, I use puppet:///modules/rehan/manifests/ntlmauth.dll because I've seen it somewhere but that does not work.

This could be a bit confusing.
In your module's directory, you should have a subdirectory named 'files' and all files you want to be copied/installed somewhere need to be put there.
The confusing bit is that when addressing one of the objects stored there, you don't mention 'files' in the path!
So,
source => 'puppet:///modules/rehan/sqljdbc4.jar'
picks up the jar file from the following path:
/etc/puppet/modules/rehan/files/sqljdbc4.jar

The reason why puppet:///modules/rehan/manifests/ntlmauth.dll doesn't work is that it maps the path to /etc/puppet/modules/rehan/files/manifests/ntlmauth.dll which doesn't exist.
You can not reference an object located in your manifests directory using puppet:///

Related

Run cmd commands with open source puppet

Can someone please help me with the open source puppet?
I want to provide a jar file to a windows client and execute the .jar file with the command line.
The .jar file is actually an update for an application which is running as a service.
I am poorly familiar with the puppet language but would guess something like this to execute the jar file:
exec { 'jar_execution':
command => 'cmd.exe /c java -jar foo.jar',
}
Should this be part of the manifest which could look like this?
service { 'fooservice':
name => foo_service,
ensure => running,
enable => true,
}
file { 'foo.jar':
path => 'C:/foo/temp/foo.jar',
ensure => file,
source => "puppet:///modules/foo/foo.jar",
}
exec { 'jar_execution':
command => 'cmd.exe /c java -jar C:/foor/temp/foo.jar',
}
And how does the agent actually run this command?
There are few architectural considerations:
Use archive resource (from archive module) instead of: file with your .jar in your module's .git history.
Have all artifacts (e.g. binary files) served by another service like Apache Archiva, Nexus or Artifactory or even Puppet Server itself. If the .jar is not developed by your company, you may want to use the authoritative source with maybe some internal caching.
Name your resources in a way that are global to your whole infrastructure, otherwise you may have events that notify themselves and produce undesired outcome.
Order of resources in puppet doesn't matter. You want to order the resources the way it makes sense to you and use the before, after, require, notify to ensure dependency.
I would recommend having binaries files outside of a module, as binaries are not supposed to be versioned. You would probably have another service that can serve files, or even your puppet infrastructure can provide those packages, in the similar way it provides the puppet-agent itself, regardless if you use Puppet OSS or Puppet Enterprise.
archive { 'C:/foo/temp/foo.jar':
source => https://location/to/your/.jar,
}
exec { 'C:/foo/temp/foo.jar': # notice in resource name recommended to use / not \
command => 'cmd.exe /c java -jar C:/foor/temp/foo.jar',
refreshonly => true # this one executes exec only if the file was re-downloaded (maybe it's signature has changed), or the file was removed from disk and was re-downloaded.
onlyif => 'test -f C:\foo\temp\foo.jar' # or some command that guards you to not run this .jar every time you run puppet
subscribe => Archive['C:/foo/temp/foo.jar'],
notify => Service['foo_service'] # most probably you need to restart the service after you ran the .jar, otherwise you wouldn't have added in your question.
}
service { 'foo_service':
ensure => running,
enable => true,
}
I notice that in your example you don't need to remove your .jar after being executed. In case you need that, another exec command can remove the file downloaded in the same

Puppet is not able to create files in C:\windows\system32 folder

I am trying to create a .ssh folder and then add id_rsa and known_hosts file into the .ssh folder in a windows 2016 server. This folder needs to get into any user who runs puppet manually(or as a service). To make this work I have written a custom fact $::user_profile_directory that figures the home directory (%userprofile%). The method works completely fine for all users except when puppet runs as a service.
When puppet runs as a service it creates the .ssh folder inside "c:/windows/system32/config/systemprofile" folder, but does not create the files in the created .ssh folder folder(id_rsa file known_hosts file). This does not happen if run the puppet service as any other user.
Puppet also does not show any errors in the logs and instead says the content was changed to specific md5 sum hash. But the .ssh folder does not contain any of the files if I go and check manually using the explorer.
Also if I place the files manually into the c:/windows/system32/config/systemprofile/.ssh folder it corrects the permissions on the files. I don't understand, if it's able to correct the permissions on the files if present, then why is it not able to create files.
Here is my simple puppet code:
$user_home = $::user_profile_directory
file { "${user_home}/.ssh":
ensure => 'directory',
#owner => $user_name,
group => 'Administrators',
mode => '0700'
} ->
file { "${user_home}/.ssh/id_rsa":
ensure => 'file',
content => hiera('vester::vester_private_key'),
#owner => $user_name,
group => 'Administrators',
mode => '0600'
} ->
file { "${user_home}/.ssh/known_hosts":
ensure => 'file',
source => 'puppet:///modules/vester/known_hosts',
source_permissions => 'ignore',
#owner => $user_name,
#group => 'Administrators',
#mode => '0660'
}
when puppet runs as service:
${user_home} is c:/windows/system32/config/systemprofile
when puppet runs as other user (let's say vagrant):
${user_home} is c:/users/vagrant
Facter code that generates the $::user_home fact:
Facter.add('user_profile_directory') do
confine :osfamily => :windows
setcode do
ENV['USERPROFILE']
end
end
EDIT 1: Just figured, I am able to create folders but not able to create files in any of the folders/subfolders under "C:/windows/system32". How can I create files in a custom folder under system32 using puppet.?
EDIT 2: JUST figured, even though $::user_profile_directory is returning
c:/windows/system32/config/systemprofile
all my files are getting placed under
c:/windows/syswow64/config/systemprofile
Puppet 32 bit client was installed on my 64 bit Windows 2016 Server.
The files were actually getting created, but instead of
c:/windows/system32/config/systemprofile/.ssh
the files were created inside
c:/windows/syswow64/config/systemprofile/.ssh
folder by my puppet client.
The %windir%\System32 directory is reserved for 64-bit applications on 64-bit Windows. Most DLL file names were not changed when 64-bit versions of the DLLs were created, so 32-bit versions of the DLLs are stored in a different directory. WOW64 hides this difference by using a file system redirector.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, %windir%\lastgood\system32, or `%windir%\regedit.exe, the access is redirected to an architecture-specific path.
It's weird since, even though files are created in c:/windows/syswow64/config/systemprofile/.ssh folder, the puppet logs in the event viewer were showing that files were being successfully created inside the c:/windows/system32/config/systemprofile/.ssh. This happened because puppet 32 bit clients are unaware of the secret redirection in windows.
The fix for me was to just remove the 32 bit puppet client and install back the 64 bit puppet client since one of my puppet-modules(puppetlabs/vsrepo) was trying to access the knownhost file from c:/windows/system32/config/systemprofile/.ssh folder as it was using 64 bit git.exe client in background.
More about the WOW64 secret redirection in Microsoft documentation here

Storage::move giving "File not found at path:" Laravel with Ubuntu

I want to move some file with
Storage::move('posts/temp/'.$val,'photos/'.$post->id.'/'.$val);
but it gives me the
File not found at path: home/vagrant/Code/......
is there some special configuration to look for? Btw, the file is indeed at the not found path.
You need to add disk() detail that you are using for example if you are using amazon s3 you need to add disk('s3') before move so the code will be:
Storage::disk('s3')->move('posts/temp/'.$val,'photos/'.$post->id.'/'.$val);
I had to change to:
'disks' => [
'local' => [
'driver' => 'local',
'root' => public_path(),
],
I had the same problem. I stored files in storage app folder (Storage/app/temp_files) for finding the files I tried public_path(), storage_path(), url() but none of this worked for me. But at the end using PHP native function rename() its worked like a charm.
Here is my example of how I implement this
rename(storage_path("app\\temp_files\\$fileNames"),storage_path("app\\post\\$fileNames"));
Where the 1st argument is for the old path and 2nd for the new path e.g.
rename($oldPath, $newPath);
Note: rename will be move(delete file from old location) your file
from old location to new location

Vagrant Puppet Class Not Found Error

I am getting the message:
Puppet::Parser::AST::Resource failed with error ArgumentError: Could not find declared class git at /tmp/vagrant-puppet-1/manifests/site.pp:15 on node vagrant-ubuntu-precise-64.wp.comcast.net
Probably the best idea is to see this in action. I have created a GitHub repo of the exact manifest I am using. It is here:
https://github.com/jamorat/puppet-example
The manifests and git module are there. If you have Vagrant, this can be vagrant up and you will see the error for yourself. Would be cool to either receive an answer here and/or also as a commit (for which credit would still be given here for answer.)
Thank you so much!
You need to configure vagrant with the puppet module path. On a side note, you would also usually keep the manifest and module folder in the same folder, instead of modules inside manifests.
This:
class{ git:
svn => 'installed',
gui => 'installed',
}
is telling puppet to create a resource based on the class named git that has 2 parameters: svn and gui. Such a class declaration doesn't exist anywhere in what you've posted. If it were, it would look something like:
class git ($svn, $gui) {
package {'svn':
ensure => $svn,
}
# Whatever 'gui' is, making package b/c use of "installed"
package {'gui':
ensure => $gui,
}
}
Alternative is to declare a class and include it using the "include" directive.
Recommend a good reading of Language: Classes

composer and site configuration files

Is it possible to install a file out of the 'vendor' directory when doing a composer install/update?
Let me elaborate a bit more if your not sure what i mean.
I have a config file(s) that are stored in /config/ini/<filename>.ini and lots of vendor modules in the vendor directory. Would it be possible to package the ini files with the vendor packages so upon installation they are written to the correct directory?
Ideally I need to be able to achieve this because i have an Authentication vendor module that will need to be installed in various different applications. Being able to do this will mean that the private key and other shared configuration options can be stored with the vendor module (in a private repo ofc).
Thanks Mike
Yes, you can. You need to create a script which is attached to post-install-cmd or post-update-cmd. That script will look in the package directories, select the issues and dump them in the correct dir.
It'll be somewhere around these lines:
use Composer\Script\CommandEvent;
class ScriptHandler
{
public function bundleConfigs(CommandEvent $event)
{
$homeDir = $event->getComposer()->getConfig()->get('home');
$vendorDir = $event->getComposer()->getConfig()->get('vendor-dir');
$files = glob($vendorDir, '/*Module/config/*.ini');
foreach ($files as $file) {
copy($file, $homeDir.'/config/ini/'.basename($file));
}
}
}

Resources