I've been messing around with puppet and i ran into an issue that has stumped me.
maybe some one can shed some light. The idea is I have an rsync script that updates my authorized_keys
file on my puppet master. Every 4 hours puppet agent grabs the new authorized_keys file.
here is a Master manifest
class policy1::sshkey {
file { '/root/.ssh/':
ensure => directory,
path => '/root/.ssh/',
owner => 'root',
group => 'root',
mode => '0700',
}
file { '/root/.ssh/authorized_keys':
require => File ["/root/.ssh/authorized_keys"],
ensure => file,
owner => 'root',
group => 'root',
mode => '0600',
source => "puppet:///modules/policy1/authorized_keys",
}
}
my agent though gets this error
Error: Failed to apply catalog: Not a directory - /root/.ssh/authorized_keys
In your manifest, specifically the second resource definition you have it requiring itself. That said, you wanna do something like below:
class policy1::sshkey {
file { '/root/.ssh/':
ensure => directory,
path => '/root/.ssh/',
owner => 'root',
group => 'root',
mode => '0700',
}
file { '/root/.ssh/authorized_keys':
# Require the parent directory to be created beforehand.
require => File['/root/.ssh/'],
ensure => file,
owner => 'root',
group => 'root',
mode => '0600',
source => "puppet:///modules/policy1/authorized_keys",
}
}
... or I personally prefer:
class policy1::sshkey {
file { '/root/.ssh':
ensure => directory,
path => '/root/.ssh',
owner => 'root',
group => 'root',
mode => '0700',
}->
file { '/root/.ssh/authorized_keys':
ensure => file,
owner => 'root',
group => 'root',
mode => '0600',
source => 'puppet:///modules/policy1/authorized_keys',
}
}
It looks like disabling the
ensure => file,
seems to do the trick. Thanks Evgeny and Felix for your help.
Related
I am trying to automate my application with cypress. Have written few tests in my class and before visiting the site I have set up cookies (To login without entering username, password and otp). I have tried several ways to store these cookies and call before each of these tests but cookies work only for the 1st test and I am logged out for the subsequent tests.
Please find my code below. I am calling data using fixtures. It works fine only when i set sso and user agent for every test and I want to eliminate this.
describe('Watchlist Testsuite', () => {
let data;
before(() => {
cy.fixture('example').then((fdata) => {
data = fdata;
});
});
it('Setting up cookies', () => {
cy.setupCookies(data.sso, data.uid, data.userAgent, data.devId, data.url)
.then(() => cy.visit(data.url))
})
it('Enter Passcode', () => {
cy.setCookie('x-sso-token', data.sso)
cy.setCookie('x-user-agent', data.userAgent)
Cypress.config('pageLoadTimeout', 2000)
cy.enterPasscode(data.passcode)
Cypress.config('pageLoadTimeout', 20000)
cy.closeOKButton()
})
it('Create a watchlist', () => {
cy.setCookie('x-sso-token', data.sso)
cy.setCookie('x-user-agent', data.userAgent)
watchlistTest.createWatchlist(data.watchlistName)
})
Below are the ways with which I tried to preserve the cookies for all tests but none of them seem to be working.
Setting up cookies in beforeeach method
beforeEach('Setup cookies', ()=> {
cy.setupCookies(data.sso, data.uid, data.userAgent, data.devId, data.url)
.then(() => cy.visit(data.url))
})
Using cookies defaults
Cypress.Cookies.defaults
({
preserve:[data.sso, data.userAgent]
})
Using cy.session (I have set experimentalSessionAndOrigin to true)
it('setting up cookies',() => {
console.log('sso is ', data.sso)
const validate = () => {
cy.getCookie(data.sso).should('exist')
}
cy.session([window.sessionStorage.setItem('x-sso-token', data.sso),
window.sessionStorage.setItem('x-uid', data.uid),
window.sessionStorage.setItem('x-user-agent', data.userAgent),
window.sessionStorage.setItem('dev-id', data.devId)], {validate})
})
PS: I am using the Cypress 10.3.1 version.
Please guide me on the right approach to solve the issue.
Let's say we have the following suite:
describe('Devices', () => {
describe('Master Data Set-Up', () => {
it('should create the device if necessary', () => {
cy.createDevice()
its('body.id')
.as('deviceId');
});
});
describe('Test Suite 1', () => {
it('should allow to send data to device', () => {
cy.get('#deviceId').then((deviceId) => {
cy.sendData(deviceId, 'Some Data');
});
});
});
});
So, we have a set up suite that creates master data. This is a simplified version, actually it contains a couple of it specs and I'd like to keep it like that because it's better to read in the Cypress output.
Then, there is the actual test suite that want's to use data that has previously been created. In this case a server generated id that should be used for another REST call.
This is assuming, that cy.createDevice and cy.sendData are custom commands available that internally use cy.request.
When running that, cy.get('#deviceId') fails because aliases are not shared across describe blocks AFAIK. I tried to use let deviceId but it's undefined as it is not yet available when the test specs are processed.
What is a proper way to do this?
I believe this will be better solution, as cypress is asynchronous so it's better to write it on file and read it
describe('Devices', () => {
describe('Master Data Set-Up', () => {
it('should create the device if necessary', () => {
cy.createDevice()
......
cy.writeFile('deviceId.txt', body.id)
});
});
describe('Test Suite 1', () => {
it('should allow to send data to device', () => {
cy.readFile('deviceId.txt').then((device_id) => {
cy.sendData(device_id, 'Some Data');
})
});
});
});
Upvote for #ArekKhatry's idea, but to be safe I would obtain the the id in a before(). If you ever run tests in parallel, grabbing data from one test to use in another would be flaky.
Note that running cy.createDevice().its('body.id') in the before() still gives you the same test coverage as running inside it(), i.e it tests that the request succeeds and the return value has an id.
The file should be written to cypress/fixtures, otherwise it will write to the project root causing untidy pollution of the file structure.
Also, the id is returned from cy.request() as a number, but must be stringifyed in order to write to a text file.
Here's my variant
describe('Devices', () => {
before(() => {
cy.createDevice()
.its('body.id')
.then(id => {
cy.writeFile('cypress/fixtures/deviceId.txt', id.toString());
cy.log(`Created device: ${id}`);
});
});
describe('Test Suite 1', () => {
it('should allow to send data to device', () => {
cy.fixture('deviceId') // can use simpler cy.fixture here
.then(device_id => { // returned as a string here
const id = parseInt(device_id); // may need to parse to number?
cy.sendData(id, 'Some Data');
})
});
});
});
Ok, so first thanks to Aloysius and Arek for their answers. But I had the gut feeling that there must be some easier way to do this that writing an Id to a file.
As I mentioned before, I had issues with my first attempt to use a global variable:
I tried to use let deviceId but it's undefined as it is not yet
available when the test specs are processed.
I really wanted to understand, why this did not work and did some console debugging.
I added a console log:
describe('Devices', () => {
console.log('Loading test suites...')
(...)
});
When running the tests, I saw the log output twice, once after the first describe block where the device id was stored and then a second time after the master data was written.
Actually, I found out that this issue was cause by the following known Cypress issue:
https://github.com/cypress-io/cypress/issues/2777
After setting the baseUrl, it actually works:
describe('Devices', () => {
let deviceId;
before( () => {
Cypress.config('baseUrl', Cypress.env('system_url'))
cy.visit('/');
})
describe('Master Data Set-Up', () => {
it('should create the device if necessary', () => {
cy.createDevice()
.its('body.id')
.then((id) => {
deviceId = id;
});
});
});
describe('Test Suite 1', () => {
it('should allow to send data to device', () => {
cy.sendData(deviceId, 'Some Data');
});
});
});
I need a way to get all my ember tests' nameS, since I want to run them in a separate thread by using the --filter "TEST-NAME" flag.
Right now, I am using a hardcoded array.
It's not documented, but you can use the config object on the root QUnit object to get all modules in your test suite, then the tests within each module and their names. Note that any tests not in a module will still appear, but with an empty-named module. Here's a runnable jsfiddle with the example, then the code below.
QUnit.test('no-module', (assert) => { assert.equal(0,0) })
QUnit.module('foobar', () => {
QUnit.test('foo', (assert) => { assert.equal(1, 1) })
QUnit.test('bar', (assert) => { assert.equal(2, 2) })
})
QUnit.module('batbaz', () => {
QUnit.test('bat', (assert) => { assert.equal(3, 3) })
QUnit.test('baz', (assert) => { assert.equal(4, 4) })
})
const testNames = []
QUnit.config.modules.forEach((module) => {
testNames.push(...module.tests.map(test => test.name))
})
console.log(testNames)
I am using Cakephp 3 for building new application where user have to login for their account however I am hitting the login URL http://localserver.com/members/login and it redirects me to http://localserver.com/users/login
Look like the 'users' controller is set by default in Auth component. How can I override the default controller from 'users' to 'members'?
NOTE: The URLs are not LIVE as I am working on my local-server.
Yes, this is related to the userModel config key, which defaults to Users.
Try this script in your controller’s beforeFilter() or initialize() methods.
// Pass settings in
$this->Auth->config('authenticate', [
'Basic' => ['userModel' => 'Members'],
'Form' => ['userModel' => 'Members']
]);
Update:
In addition to userModel to be worked properly you must set the loginAction too.
// Pass settings in
$this->Auth->config('authenticate', [
'loginAction' => [
'controller' => 'Members',
'action' => 'login',
'plugin' => false, // or 'Members' if plugin
],
'Basic' => ['userModel' => 'Members'],
'Form' => ['userModel' => 'Members']
]);
Cookbook 3.x Doc
I am new to vagrant and chef. I spin up my Vm using Vagrant and provision it using Chef-solo. I add the cookbook for glassfish downloaded from opscode chef. Glassfish is installed, but not started. I have given in my vagrantfile
chef.add_recipe "glassfish::attribute_driven_domain"
chef.json = {
"glassfish" => {
"base_dir" => "/usr/local/glassfish",
"domains_dir" => "/usr/local/glassfish/glassfish/domains",
"domains" => {
"domain1" => {
"config" => {
"domain_name" => "domain1",
"admin_port" => 4848,
"username" => "root",
"password" => "admin",
"remote_access" => true
}
}
}
}
}
You only called the glassfish::attribute_driven_domain recipe. To create the domain you also have to call the glassfish::default recipe.
The glassfish::default recipe creates the domain.xlm template used as base for the Glassfish domain.