Getting the puppet module pcfens/filebeat to work - ruby

I'm new to this site and puppet. I'm trying so setup a puppet module for filebeat. I want Linux nodes to send logs to logstash using this module
I want a configuration that looks something like this:
class { 'filebeat':
outputs => {
'logstash' => {
'hosts' => [
'<FQDN>:5044',
],
'enabled' => true,
},
},
}
filebeat::prospector { 'syslogs':
paths => [
'/var/log/*.log',
'/var/log/messages',
],
doc_type => 'syslog-beat',
}
Does anyone have any experience with this module or with Puppet in general and can tell me how to configure this module with the configuration above. I feel clueless right now and I can't seem to find a lot of documentation about this module. I would really appreciate a push into the right direction on how to setup this module.

You probably want to ask about how to start your Control Repo. But before you do that, make sure you read up on the Roles and Profiles design pattern.
To get you started, you will have start something like this:
$ tree
.
└── modules
├── profile
│   └── manifests
│   ├── base
│   │   └── filebeat.pp
│   └── base.pp
└── role
└── manifests
├── base
└── myrole.pp
7 directories, 3 files
(Obviously, as you can see from the example I linked above, it is going to have a lot more in it eventually.)
Then your base class:
$ cat modules/profile/manifests/base.pp
class profile::base {
include profile::base::filebeat
}
Which includes (the code you wrote above):
$ cat modules/profile/manifests/base/filebeat.pp
class profile::base::filebeat {
class { 'filebeat':
outputs => {
'logstash' => {
'hosts' => [
'<FQDN>:5044',
],
'enabled' => true,
},
},
}
filebeat::prospector { 'syslogs':
paths => [
'/var/log/*.log',
'/var/log/messages',
],
doc_type => 'syslog-beat',
}
}
Your role:
$ cat modules/role/manifests/myrole.pp
class role::myrole {
include profile::base
}
Now, you can test the code on the local host just by ensuring that your modules directory gets copied one way or another into Puppet's modulepath.
If so, try:
# puppet module install pcfens/filebeat
# puppet apply -e 'include role::myrole'
Providing you installed Puppet correctly, and your code above is correct, that would get you started.

Related

Best way to override single method in Illuminate\Foundation\Application through service provider

I just made changes to the application structure for my Laravel application. It works well when runnning tests (for the Http controllers). The problem is when i try to run artisan commands (that literally need to access "getNamespace()" method), it wont resolve the namespaces.
Here are the composer.json:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/",
"Modules\\": "modules/"
},
"files": [
"app/Helpers/app.php",
"app/Helpers/form.php",
"app/Helpers/view.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
I do aware that i can add Modules\ModuleA, Modules\ModuleB to the composer json, but that put alot of work. So i decided to override the getNamespace() method instead, but what is the best way to override single method illuminate/foundation/xxx classes through service provider?
Folder tree:
laravel-project/
├── app/
│ ├── Exception
│ ├── Providers
│ └── ...
├── modules/
│ ├── ModuleA/
│ │ ├── Services
│ │ ├── Http/
│ │ │ ├── Controllers
│ │ │ └── Requests
│ │ └── Models
│ └── ModuleB/
│ └── ...
├── tests
└── ...
If you want to override a single method in Illuminate\Foundation\Application through a service provider in Laravel, you can use the following steps:
Create a new service provider by running the command php artisan make:provider YourServiceProvider in your terminal.
In your YourServiceProvider class, extend the Illuminate\Support\ServiceProvider class.
Override the register() method in your YourServiceProvider class. In this method, you can bind your custom implementation of the method you want to override to the container. For example, if you want to override the loadEnvironmentFrom() method, you can do so as follows:
use Illuminate\Foundation\Application;
class YourServiceProvider extends ServiceProvider
{
public function register(){
$this->app->bind(Application::class, function ($app) {
return new class($app) extends Application {
public function loadEnvironmentFrom($file)
{
// Your custom implementation here
}
};
});
}
}
Then in your config.app file, add the service provider to the list of providers:
'providers' => [
// Other service providers
App\Providers\YourServiceProvider::class,
],
This way, the method you've overridden will use your custom implementation instead of the default implementation in Illuminate\Foundation\Application.
Hope this helps

Failure: Cannot find module handler AWS Lambda

Hello I am trying to setup a new serverless graphql project but the serverless.yml file doesn't find my handler, which is in src/graphql.ts
It throws an error like this:
Failure: Cannot find module '/Users/VIU/Projects/am/src/graphql'
The src is in the root directory and the path is correct, so I don't understand what is going on.
The serverless.yml looks like this:
graphql:
handler: src/graphql.graphqlHandler
events:
- http:
path: graphql
method: post
cors: true
- http:
path: graphql
method: get
cors: true
And the graphql handler file like this:
import { ApolloServer, gql } from "apollo-server-lambda"
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
type Query {
hello: String
}
`;
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
};
const server = new ApolloServer({ typeDefs, resolvers });
exports.graphqlHandler = server.createHandler();
I've also tried
module.exports.graphqlHandler = server.createHandler();
export const graphqlHandler = server.createHandler();
But none of that seems to work either.
Has someone any idea of what I am doing wrong? Thank You!
In order to run an AWS Lambda function with a Node.js runtime, you'll need to provide a .js file as its handler. Specifically, when using TypeScript and the Serverless framework, that means that the handler field must refer to the compiled file name, namely, ending with a .js extension.
One option for you to resolve this is to simply change the handler field to point to the compiled version of your file. For example, given the following structure:
├── am
│ ├── built
│ │ └── graphql.js
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ └── graphql.ts
└── serverless.yaml
The correct handler field is:
graphql:
handler: built/graphql.graphqlHandler
However, another option which I believe is the preferred one (and possibly what you were originally aiming for) is to use the serverless-plugin-typescript plugin of the Serverless framework. That should reduce your efforts and allow you to use TypeScript almost seamlessly. There is actually an example provided by Serverless that is very similar to your need and I think you can find useful.

Combining GraphQL queries

I am building my first GraphQL based project so forgive me if this is a newbie question. I have arranged my queries and mutations in the following fashion:
├── graphql
│   ├── lessons
│   │   ├── logic.js
│   │   ├── query.js
│   │   ├── schema.js
│   │   └── types.js
│   ├── schema.js
│   └── users
│   ├── logic.js
│   ├── mutation.js
│   ├── query.js
│   ├── schema.js
│   └── types.js
This is my users/query.js file:
const graphql = require('graphql')
const types = require('./types.js')
const logic = require('./logic.js')
module.exports = new graphql.GraphQLObjectType({
name: 'UserQuery',
fields: {
user: {
type: types.userType,
args: {
email: { type: new graphql.GraphQLNonNull(graphql.GraphQLString) }
},
resolve: (root, { email }, context) => logic.getUser(email, context)
}
}
})
In my schema.js, I have combined the queries of users and lessons as per the following code:
module.exports = new graphql.GraphQLSchema({
query: new graphql.GraphQLObjectType({
name: 'RootQuery',
fields: {
lessons: { type: require('./lessons/query.js') },
users: { type: require('./users/query.js') }
}
})
})
Now the problem is, the following query:
{
users {
user(email: "a#.a") {
name,
purchases
}
}
}
is producing the following output:
{
"data": {
"users": null
}
}
I am getting a null in place of a user record. What am I doing wrong here?

Terraform: how to not duplicate security groups when creating it using modules?

Update
I don't get it, but I reran terraform apply and it did not try to duplicate resources (no errors). Now it checks resources correctly. Kind of unexpected end of events.
I'm learning Terraform, and I created module to allow creating some basic security groups. It runs fine first time and creates resources as expected. But if I run terraform apply second time, it tries to create same groups again and then I get duplicate error, because such security groups already exist.
If I would create security groups directly without module, Terraform recognizes it and does not try to recreate existing resources.
I probably do something wrong here.
Here is my module and how I try to use it:
My project structure looks like this
├── main.tf
├── modules
│   ├── security_group_ec2
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── security_group_rds
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── scripts
│   └── update-odoo-cfg.py
├── security_groups.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── variables.tf
└── vpc.tf
Now my security_group_ec2 content:
main.tf:
resource "aws_security_group" "sg" {
name = "${var.name}"
description = "${var.description}"
vpc_id = "${var.vpc_id}"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
variables.tf:
variable "name" {
description = "Name of security group"
}
variable "description" {
description = "Description of security group"
}
variable "vpc_id" {
description = "Virtual Private Cloud ID to assign"
}
outputs:
output "sg_id" {
value = "${aws_security_group.sg.id}"
}
And this is file were I call module to create two security groups.
security_groups.tf:
# EC2
module "security_group_staging_ec2" {
source = "modules/security_group_ec2"
name = "ec2_staging_sg"
description = "EC2 Staging Security Group"
vpc_id = "${aws_default_vpc.default.id}"
}
module "security_group_prod_ec2" {
source = "modules/security_group_ec2"
name = "ec2_prod_sg"
description = "EC2 Production Security Group"
vpc_id = "${aws_default_vpc.default.id}"
}
This is error output when running terraform apply:
module.security_group_staging.aws_security_group.sg: Destruction complete after 1s
module.security_group_prod.aws_security_group.sg: Destruction complete after 1s
Error: Error applying plan:
2 error(s) occurred:
* module.security_group_staging_ec2.aws_security_group.sg: 1 error(s) occurred:
* aws_security_group.sg: Error creating Security Group: InvalidGroup.Duplicate: The security group 'ec2_staging_sg' already exists for VPC 'vpc-2a84a741'
status code: 400, request id: 835004f0-d8a1-4ed5-8e21-17f01eb18a23
* module.security_group_prod_ec2.aws_security_group.sg: 1 error(s) occurred:
* aws_security_group.sg: Error creating Security Group: InvalidGroup.Duplicate: The security group 'ec2_prod_sg' already exists for VPC 'vpc-2a84a741'
status code: 400, request id: 953b23e8-20cb-4ccb-940a-6a9ddab54d53
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
P.S. I probably need to somehow indicate that resource is created when calling module?
This looks like a race condition. Terraform tries to parallelise the creation of resources which do not depend on each other, and in this case it looks like it tried to destroy the security groups from module.security_group_staging while simultaneously trying to create them in module.security_group_staging_ec2 with the same names. Did you rename security_group_staging into security_group_staging_ec2?
The destruction succeeded, but the creation failed, because it ran in parallel with destruction.
The second time you ran it there was no race condition, because module.security_group_staging was already destroyed.
As a side note, it is usually a good idea to not keep separate environments in the same state file.

Static files not working in Django development

I'm trying to follow the section in the Django docs called Managing static files. I am interested in finding out:
What I am doing wrong.
Or, what is wrong with the Django docs.
1) Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
In the default settings.py file:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles', #<****HERE*****
)
2) In your settings file, define STATIC_URL, for example: STATIC_URL = '/static/'
In the default settings.py:
STATIC_URL = '/static/'
3) In your templates, either hardcode the url like /static/my_app/myexample.jpg
In mysite2/mysite2/views.py:
from django.http import HttpResponse
def index(request):
return HttpResponse('''
<h2>Hello</h2>
<img src="/static/mysite2/Aerial03.jpg">
''')
4) Store your static files in a folder called static in your app. For example: my_app/static/my_app/myimage.jpg.
Here is my directory structure:
(django186p34)~/django_projects$ tree mysite2
mysite2
├── db.sqlite3
├── manage.py
└── mysite2
├── __init__.py
├── settings.py
├── static #<****HERE*****
│   └── mysite2
│   └── Aerial03.jpg
├── urls.py
├── views.py
└── wsgi.py
4 directories, 13 files
But after starting the server:
(django186p34)~/django_projects/mysite2$ python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
November 26, 2015 - 02:44:57
Django version 1.8.6, using settings 'mysite2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
And then navigating in my browser to:
http://localhost:8000/
I see the text:
Hello
but the image is not found:
[Error] Failed to load resource: the server responded with a status of 404 http://localhost:8000/static/mysite2/Aerial03.jpg
I've tried many combinations of urls in my html and nothing works.
Here is settings.py in its entirety(I made no changes):
"""
Django settings for mysite2 project.
Generated by 'django-admin startproject' using Django 1.8.6.
For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'pmaup3%)m09cs2goldduw2iogso%(#8cz0s-zmr%*e'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
ROOT_URLCONF = 'mysite2.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'mysite2.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
This fixed things:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'mysite2', #<*****HERE*****
)
And if you organize things so that you have apps inside your project, e.g.:
(django186p34)~/django_projects$ tree mysite3
mysite3
├── db.sqlite3
├── manage.py
├── myapp
│   ├── __init__.py
│   ├── admin.py
│   ├── migrations
│   │  
│   │  
│   ├── models.py
│   ├── static
│   │   └── myapp
│   │   └── Aerial03.jpg
│   ├── tests.py
│   ├── urls.py
│   └── views.py
└── mysite3
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
8 directories, 24 files
Then in settings.py add your app name to INSTALLED_APPS:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', #<*****HERE*****
)
Everything else in the default settings.py stays the same. However, the urls are different:
mysite3/mysite3/urls.py:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^myapp/', include('myapp.urls')),
]
mysite3/myapp/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
And in your browser, the url becomes:
http://localhost:8000/myapp/
myapp/views.py:
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse('''
<h2>Hello</h2>
<img src="/static/myapp/Aerial03.jpg">
''')

Resources