Puppet can be so frustrating sometimes.
I have multiple nodes that use a service "poodle", and it has been configured this way.
# SITE.PP
node 'tweedle.example.com' {
include basicstuff
include poodle
}
node 'beetle.example.com' {
include basicstuff
include poodle
}
## POODLE MODULE, manifests/init.pp
class poodle {
class {'poodle::install': }
class {'poodle::config': }
class {'poodle::service': }
Class ['poodle::install'] -> Class ['poodle::config'] ~> Class ['poodle::service']
}
...
class poodler::service {
service {'poodle':
ensure => 'running',
enable => true,
restart => "/etc/init.d/poodle stop && sleep 5 && /etc/init.d/poodle start",
subscribe => File['/opt/poodle/poodle.py'],
}
}
Now, let's say that I no longer need to run poodle on the "beetle" machine. How do I go about stopping the service on only that machine?
I've tried passing ensure => stopped, but I get a syntax error:
node 'beetle.example.com' {
include basicstuff
class poodle::service {
ensure => 'stopped'
}
}
Or maybe?
node 'beetle.example.com' {
include basicstuff
include poodle::service {
ensure => 'stopped'
}
}
Add a parameter to your service class that can be used for the ensure parameter on the service, like so
class poodler::service ($ensure = 'running') {
service {'poodle':
ensure => $ensure,
enable => true,
restart => "/etc/init.d/poodle stop && sleep 5 && /etc/init.d/poodle start",
subscribe => File['/opt/poodle/poodle.py'],
}
}
Then instead of including the class like your second attempt does, create the class as a resource and set the value of $ensure.
node 'beetle.example.com' {
include basicstuff
class {'poodle::service':
ensure => 'stopped',
}
}
That should kill the service.
Since the default for the $ensure paramater is set to running, you don't need to specify that when you actually want it running.
Can parameterize other parts of your classes if you want that could cause the app to be completely removed if you wanted to.
Good reading on this subject is at: Learning Puppet — Class Parameters
Related
I need your help, I am using Eloquent and enssegers / laravel-mongodb outside Laravel Framework, I have managed to correctly configure both Eloquent and laravel-mongodb and it works correctly to insert and obtain results, however, when trying to modify a registry, eloquent loses the connection name by throwing the following error:
Argument 1 passed to Jenssegers\Mongodb\Query\Builder::__construct() must be an instance of Jenssegers\Mongodb\Connection, instance of Illuminate\Database\MySqlConnection given, called in /www/html/syberianbox/sachiel/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Eloquent/Model.php on line 421
I share the configuration of Eloquent through Capsula and laravel-mongodb
$this->_capsule = new Capsule();
$this->_capsule->getDatabaseManager()->extend('mongodb', function($config) {
return new MongodbConnect($config);
});
//MySQL connection, $ this -> _ config contains an array with the correct values
$this->addConnection('default', [
'driver' => $this->_config['default']['driver']
,'host' => $this->_config['default']['host']
,'database' => $this->_config['default']['database']
,'username' => $this->_config['default']['username']
,'password' => $this->_config['default']['password']
,'charset' => $this->_config['default']['charset']
,'collation' => $this->_config['default']['collation']
,'prefix' => $this->_config['default']['prefix']
]);
//MongoDB connection
$this->addConnection('archivos', [
'driver' => $this->_config['archivos']['driver']
,'host' => $this->_config['archivos']['host']
,'port' => $this->_config['archivos']['port']
,'database' => $this->_config['archivos']['database']
]);
Model:
<?php
namespace Instances\Generic\Models\CFDI;
use Jenssegers\Mongodb\Eloquent\Model;
class Archivo extends Model
{
protected $collection = 'cfdi';
protected $connection = 'archivos';
}
Execute model:
$archivoDB = Archvio::Where('_id',$id)->first();
$this->_logger->info('Archivo: ', $archivoDB);
$archivoDB->uuid = $uuid;
$archivoDB->type = $type;
$archivoDB->content = $content;
$archivoDB->save();
Logger:
[2019-02-12 14:20:36:511603][Instances/Generic/Modules/Administracion/ArchivosController.php : 75][Info][30117] Archivo:
Instances\Generic\Models\CFDI\Archivo Object
(
[collection:protected] => cfdi
[connection:protected] =>
[primaryKey:protected] => _id
[keyType:protected] => string
.....
I was able to solve the problem, however it is more a patch than a complete solution.
I extend the class Model of jenssegers / laravel-mongodb and on I write the method getConnectionName () and return the name of the expected connection, as in my case it is only a single connection the name remains as static, however, the method gives the arrow to be able to include all the necessary logic to identify the connection with the model in question
Model:
<?php
namespace Syberianbox\Db;
use Jenssegers\Mongodb\Eloquent\Model;
class Monomodel extends Model
{
public function getConnectionName() {
return 'archivos';
}
}
After tackling this other question we would now like to check if the authenticated user can view, update or delete an existing record. Since checkAccess() is called by default in all restActions the following seemed the most logic thing to try:
public function checkAccess($action, $model = null, $params = []) {
if(in_array($action, ['view', 'update', 'delete'])) {
if(Yii::$app->user->identity->customer->id === null
|| $model->customer_id !== Yii::$app->user->identity->customer->id) {
throw new \yii\web\ForbiddenHttpException('You can\'t '.$action.' this item.');
}
}
}
But the API seems to ignore this function. We added this function in our controller. The actions (view, update and delete) are the default restActions.
Our BaseController sets actions like this:
...
'view' => [
'class' => 'api\common\components\actions\ViewAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
'scenario' => $this->viewScenario,
],
...
Are we forgetting something?
Just add the following inside your custom action before executing any other code as it was done in the default view action (see source code here):
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id, $model);
}
note: $this->checkAccess is defined in parent yii\rest\Action so your custom ActionView class need to either extend yii\rest\Action or redefine the variable public $checkAccess;
We obviously should have seen that the viewAction is not the default but an altered api\common\components\actions\ViewAction ... Not sure how we missed that...
I can't understand how to restart service from another class.
My structure is:
# cat init.pp
class nginxrtmp {
include nginxrtmp::nginxinstall
include nginxrtmp::nginxconfig
}
in nginxrtmp::nginxinstall i have service nginx to restart
# cat nginxinstall.pp
service {'nginx':
name => 'nginx.service',
ensure => 'running',
enable => 'true',
}
And in nginxrtmp::nginxconfig i have *.erb template with config
# cat nginxconfig.pp
file { '/etc/nginx/nginx.conf':
* => $resAttributes,
content => template('nginxrtmp/redhat.nginx.conf.erb'),
notify => nginxinstall::Service['nginx'],
}
And my question is, how to restart service nginx described in another class and file *.pp if my template file change
I just found answer myself. Need to write
include nginxrtmp::nginxinstall
in class with config
You could create a service.pp file that contains the service and then change it to:
# init.pp
class nginxrtmp {
contain nginxrtmp::service
contain nginxrtmp::config
Class['::nginxrtmp::config']
~> Class['::nginxrtmp::service']
}
# service.pp
service { 'nginx':
name => 'nginx.service',
ensure => 'running',
enable => 'true',
}
# config.pp
file { '/etc/nginx/nginx.conf':
* => $resAttributes,
content => template('nginxrtmp/redhat.nginx.conf.erb'),
}
Take a look at: https://docs.puppet.com/puppet/4.10/bgtm.html and this section in regarding to ordering https://docs.puppet.com/puppet/4.10/bgtm.html#c-ordering
Basically I have multiple API applications in one Sinatra / GrapeAPI file
require 'sinatra'
require 'grape'
require 'webrick'
require 'webrick/https'
require 'openssl'
CERT_PATH = '/opt/myCA/server/'
class WebApp < Sinatra::Base
post '/' do
"Hellow, world!"
end
end
class Api1 < Grape::API
get '/test1' do
{xyz: 'test1' }
end
end
class Api2 < Grape::API
get '/test2' do
{xyz: 'test2' }
end
end
webrick_options1 = {
:Port => 8443,
:Logger => WEBrick::Log::new($stderr, WEBrick::Log::DEBUG),
:DocumentRoot => "/ruby/htdocs",
:SSLEnable => true,
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
:SSLCertificate => OpenSSL::X509::Certificate.new( File.open(File.join(CERT_PATH, "my-server.crt")).read),
:SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open(File.join(CERT_PATH, "my-server.key")).read),
:SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ]
}
webrick_options2 = {...}
Rack::Handler::WEBrick.run Api1, webrick_options1 # this will work
Rack::Handler::WEBrick.run Api2, webrick_options2 # but when I try another one,
# the other will not
Grape gem is recommending to use cascade:
run Rack::Cascade.new [Api1, Api2, WebApp]
However this will ignore my precious SSL settings.
How can I run multiple server configurations?
I'm very new to Puppet, and can't seem to find the answer to this question. I have a defined Puppet resource that takes a few arguments:
class xy::xy {
include apache:regular_apache
define setup($pkg_name, $xy_version, $pas_ver) {
file { '/etc/xy':
ensure => present,
notify => Service['apache'],
}
}
I'm trying to require this custom resource for another resource in another file.
class soft::buy {
include xy::xy
$xt_requires = [Xy::Xy::Setup["{'xt_buy': pkg_name => 'xt_buy_v01',
xy_version => '1.0.1',
pas_version => '2.1.4'}"]]
package { 'buy.xt':
ensure => $::buy_xt_version,
provider => 'xt',
require => $xt_requires,
}
}
The error that I get is this: Syntax error at 'require'; expected '}'
From reading the Puppet docs, it seems like I'm missing a comma or colon somewhere, but I've tried a variety of things. I was wondering how to properly require a custom defined resource with parameters for another resource? Thanks!
The syntax error can be fixed by the following code snippet.
package { 'buy.xt':
ensure => $::buy_xt_version,
provider => 'xt',
require => $xt_requires
}
[EDIT: The original code defines $xt_requires, not $requires]
You are defining the parameter require (which defines which resource needs to be handled first).
This is different from the language statement require (which is including a class and adding a dependency on the required class).
However, in the require-paramter, you cannot specify the parameters for the requirement, just it's presence. Fully correct would be:
xy::xy::setup {'xt_buy':
pkg_name => 'xt_buy_v01',
xy_version => '1.0.1',
pas_version => '2.1.4'
}
package { 'buy.xt':
ensure => $::buy_xt_version,
provider => 'xt',
require => Xy::Xy::Setup['xt_buy']
}