404 The resource could not be found - pyramid

Getting 404 Resource not found when trying to access a single item as anonymous i.e. no authenticated. I would expect instead a 403 Forbidden since I have setting permission on the view config.
class BookShow(FormView):
"""Show one instance of a model."""
resource_buttons = [...]
#view_config(route_name="book", context=BookResource, name="", renderer="site/workspace/book/single.html", permission="authenticated")
def book(self):
...
return locals()
My views init has the traversal set as:
self.config.add_route('book', '/book/*traverse', factory="bookstoreapp.views.bok.views.book_container_factory")
Log shows that the route was matched though then shows 404 debug_notfound:
2017-04-08 12:36:09 mamachine pyramid_debug[685] DEBUG route matched for url http://localhost:6543/book/8LjkOSzGSR67i1dnGUOg-Q; route_name: 'book', path_info: '/book/8LjkOSzGSR67i1dnGUOg-Q', pattern: '/book/*traverse', matchdict: {'traverse': ('8LjkOSzGSR67i1dnGUOg-Q',)}, predicates: ''
2017-04-08 12:36:09 mamachine pyramid_debug[685] DEBUG debug_notfound of url http://localhost:6543/book/8LjkOSzGSR67i1dnGUOg-Q; path_info: '/book/8LjkOSzGSR67i1dnGUOg-Q', context: <bookstoreapp.views.book.views.BookContainer object at 0x7eff6d5d1fd0>, view_name: '8LjkOSzGSR67i1dnGUOg-Q', subpath: (), traversed: (), root: <bookstoreapp.views.book.views.BookContainer object at 0x7eff6d5d1fd0>, vroot: <bookstoreapp.views.book.views.BookContainer object at 0x7eff6d5d1fd0>, vroot_path: ()
The view render fine when the user is logged in just that when not, I would like to get Forbidden view instead.

It looks like your context is BookContainer with a view_name of 8LjkOSzGSR67i1dnGUOg-Q. This does not match your required context of BookResource with a name of '' and thus would be a 404 before permissions are checked. You probably want to drop the name predicate from your view_config because you probably do not care what the name is. Also figure out why the context is not what you expect based on what's happening in your traversal tree.

Related

Unable to perform update on my question in SPFX. Uncaught (in promise) Error: Error making HttpClient request in queryable [400] odata.error

I have fixed this issue on one of my earlier projects but it seems like I am unable to do it on this project and I don't know why.
The fix that I have done earlier was by adding delete updateFAQ["odata.metadata"]
Though the error vscode gives now is the following:
Element implicitly has an 'any' type because expression of type '"odata.metadata"' can't be used to index type 'IFAQ. Property 'odata.metadata' does not exist on type 'IFAQ'
For context the method looks like this:
public async updateFAQ(updateFAQ: IFAQ): Promise<void> {
delete updateFAQ["odata.metadata"] //vscode gives an error
await this._sp.web.lists.getById(this.faqListId).items.getById(updateFAQ.ID).update(updateFAQ);
}
Can someone give some guidance on why the error occurs and why delete updateFAQ["odata.metadata"] gives an error?
If there is anything that you need context to just say the word.
The full error in the console looks like this: Uncaught (in promise) Error: Error making HttpClient request in queryable [400] ::> {"odata.error":{"code":"-1, Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":"en-US","value":"A relative URI value 'Web/Lists(guid'e6197c8f-88c1-47c4-911e-538ee0638250')/Items(25)' was specified in the payload, but the odata.metadata annotation is missing from the payload. The payload must only contain absolute URIs or the odata.metadata annotation must be on the payload."}}} at HttpRequestError.init (parsers.js:96:1) at async Proxy.errorCheck (parsers.js:45:1) at async queryable.js:118:1
EDIT: Interface
export interface IFAQ {
ID?: number;
Question: string;
Answer: string;
}
UPDATE/SOLUTION
I've got it fixed. What I did was by mapping the result sp.web.lists into an object called finalResultwhere I set the object properties to the properties of the IFAQ. Then I return finalResult. In that way I choose that I only want to return the properties of the IFAQ and not any metadata or odata:
public async getFAQ(): Promise<IFAQ[]> {
let result: IFAQ[] = await this._sp.web.lists.getById(this.faqListId).items();
let finalReuslt = result.map((x) => ({
ID: x.ID,
Question: x.Question,
Answer: x.Answer
}))
return result;
}

SwiftUI. Access to properties from background

This problem is driving me crazy.
In principle the code below works correctly.
The authenticator that is called is a class defined in its own module (Authenticator.swift).
The code below is a method of the viewModel that conforms ObservableObject protocol.
The observed properties self.error and self.goToHomeView are properties published from the viewModel.
The authenticator method authenticates with FaceID. If authentication succeeds, error is nil, then the observed variable goToHomeView is set to true to switch to the Home view.
If error is not nil, then self.error is assigned which is of type LocalizedError and that triggers an alert in the view.
The problem is that an annoying warning appears all the time saying: "Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.”
I would like to know if anyone knows a technically valid way to modify values from the main thread from a secondary thread running in background.
Task {
await authenticator.authenticate { error in
if let error = error {
self.error = error
} else {
self.goToHomeView = true
}
}
}

Reading nested attribute in data source (of a Cloud Run service that might not exist) in Terraform

I'm using Terraform v0.14.4 with GCP. I have a Cloud Run service that won't be managed with Terraform (it might exist or not), and I want to read its url.
If the service exists this works ok:
data "google_cloud_run_service" "myservice" {
name = "myservice"
location = "us-central1"
}
output "myservice" {
value = data.google_cloud_run_service.myservice.status[0].url
}
But if it doesn't exist, I can't get it to work!. What I've tried:
data.google_cloud_run_service.myservice.*.status[*].url
status is null
length(data.google_cloud_run_service.myservice) > 0 ? data.google_cloud_run_service.myservice.*.status[0].url : ""
Tried with join("", data.google_cloud_run_service.myservice.*.status)
I get this error: data.google_cloud_run_service.myservice is object with 9 attributes
coalescelist(data.google_cloud_run_service.myservice.*.status, <...>)
It just returns [null], and using compact over the result gets me a Invalid value for "list" parameter: element 0: string required.
Any ideas?
It seems like you are working against the design of this data source a little here, but based on the error messages you've shown it seems like the behavior is that status is null when the requested object doesn't exist and is a list when it does, and so you'll need to write an expression that can deal with both situations.
Here's my attempt, based only on the documentation of the resource along with some assumptions I'm making based on the error message you included:
output "myservice" {
value = (
data.google_cloud_run_service.myservice.status != null ?
data.google_cloud_run_service.myservice.status[0].url :
null
)
}
There is another potentially-shorter way to write that, relying on the try function's ability to catch dynamic errors and return a fallback value, although this does go against the recommendations in the documentation in that it forces an unfamiliar future reader to do a bit more guesswork to understand in which situations the expression might succeed and which it might return the fallback:
output "myservice" {
value = try(data.google_cloud_run_service.myservice.status[0].url, null)
}

Puppet nested resources create_resources, can't convert string into hash

trying to build a DNS with this module: ref. But getting this error:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, can't convert String into Hash.
I have nested YAML, but not sure if it's correctly formatted or not or problems with something else within my code.
This is my dns profile dns.pp:
class profile::bind {
validate_hash($conf)
$conf = hiera_hash('bind::zone', undef)
create_resources('profile::bind::make::zone', $conf)
}
This is how I define my zone with make_zone.pp:
define profile::bind::make::zone (
$hash_data,
$zone,
$ensure,
$zone_contact,
$zone_ns,
$zone_serial,
$zone_ttl,
$zone_origin,
) {
validate_hash($hash_data)
bind::zone { $zone :
ensure => $ensure,
zone_contact => $zone_contact,
zone_ns => [$zone_ns],
zone_serial => $zone_serial,
zone_ttl => $zone_ttl,
zone_origin => $zone_origin,
}
}
This is my host1.yaml data:
---
version: 5
bind::zone:
zone: test.ltd
ensure: present
zone_contact: 'contact.test.ltd'
zone_ns:
-'ns0.test.ltd'
-'ns1.test.ltd'
zone_serial: '2018010101'
zone_ttl: '767200'
zone_origin: 'test.ltd'
hash_data:
"newyork":
owner: "11.22.33.44"
"tokyo":
owner: "22.33.44.55"
"london":
owner: "33.44.55.66"
bind::cname:
ensure: present
record_type: master
There are a number of mistakes and misunderstandings in the code. I fixed them up so that the code at least compiles and ended up with this.
Changes to profile::bind:
class profile::bind {
include bind
$conf = lookup('bind::zone')
create_resources(profile::bind::make::zone, $conf)
}
Changes to profile::bind::make::zone:
define profile::bind::make::zone (
Enum['present','absent'] $ensure,
String $zone_contact,
Array[String] $zone_ns,
String $zone_serial,
String $zone_ttl,
String $zone_origin,
Hash[String, Hash[String, String]] $hash_data,
) {
bind::zone { $name:
ensure => $ensure,
zone_contact => $zone_contact,
zone_ns => $zone_ns,
zone_serial => $zone_serial,
zone_ttl => $zone_ttl,
zone_origin => $zone_origin,
}
}
Changes to host1.yaml:
---
bind::zone:
'test.ltd':
ensure: present
zone_contact: 'contact.test.ltd'
zone_ns:
- 'ns0.test.ltd'
- 'ns1.test.ltd'
zone_serial: '2018010101'
zone_ttl: '767200'
zone_origin: 'test.ltd'
hash_data:
"newyork":
owner: "11.22.33.44"
"tokyo":
owner: "22.33.44.55"
"london":
owner: "33.44.55.66"
Some explanation:
immediate problem:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, can't convert String into Hash.
This error was caused because your Hiera data was not correctly structured as a Hash[String, Hash[String, String]]. Notice in the yaml I have removed your key "zone" and created a nested Hash there.
must include the bind class
The camptocamp BIND module requires the bind class to also be declared. See its documentation.
validate_hash function is legacy and in the wrong place
As John Bollinger mentioned in the comment, you had the validate_hash on the wrong line. I think that was a cut/paste issue, because you would have got a different error message if that was really your code. Anyway, since you're using Puppet 5 (I guess that by the version => 5 in your Hiera), don't use the legacy validate functions ; use Puppet's data type validation. So I just deleted that line.
use lookup() instead of hiera_hash()
Again, since you're using Puppet 5, use the lookup() function instead of the deprecated hiera_hash() function.
version 5 belongs in hiera.yaml, not host1.yaml
It won't cause you any problems, but the line version: 5 won't do anything here, and it belongs in your hiera.yaml file. I used a hiera.yaml file as follows for testing:
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Host 1"
paths:
- host1.yaml
zone_ns type confusion
You had 2 problems with the zone_ns - firstly, a typo in your YAML (no space after the -) ; and secondly, you passed in an Array of zone NS's and then tried to coerce the array to an array in your defined type.
zone parameter should be the name var
Notice I had to delete the $zone parameter in your defined type, and I used the special $name variable instead, to get the name from the title.
refactored to use data type validation
Notice how I used Puppet's data type validation on your inputs in the defined type, and then I had no further need for the legacy validate_hash function and other related validate functions. Read more about that here.
I think that's all. Hope that helps!

Puppet Can't Find Variable for Template

Just getting started with Puppet, and I'm having trouble with my first template. It should be very easy, but I can't figure it out.
I have a module "base" at
/etc/puppet/modules/base/
./manifests
./manifests/service.pp
./manifests/init.pp
./manifests/params.pp
./manifests/config.pp
./manifests/install.pp
./templates
./templates/puppet.conf.erb
There's other stuff, but it's not necessary.
base/manifests/init.pp:
class base {
include base::install, base::service, base::config, base::params
}
base/manifests/config.pp
class base::config {
include base::params
File {
require => Class["base::install"],
ensure => present,
owner => root,
group => root,
}
file { "/etc/puppet/puppet.conf":
mode => 0644,
content => template("base/puppet.conf.erb"),
require => Class["base::install"],
nofity => Service["puppet"],
}
...
base/manifests/params.pp
class base::params {
$puppetserver = "pup01.sdirect.lab"
}
Finally the interesting part of the template at base/templates/puppet.conf.erb
...
server=<% puppetserver %>
The error message:
err: Failed to parse template base/puppet.conf.erb: Could not find
value for 'puppetserver' at
/etc/puppet/modules/base/manifests/config.pp:13 on node ...
I don't get what the problem is. I've copied this part straight out of the Pro Puppet book.
Could someone show me where $puppetserver should be defined and how?
The issue is that the name "puppetserver" needs to be fully qualified so Puppet can find the value, since it's defined in a different scope to the one the template is evaluated in.
The variable is defined in base::params so can only be referred to simply as "puppetserver" in that scope. When you're evaluating the template from within base::config, you're in a different scope and so you can't refer to the variable simply by its short name. The "include" adds the other class to the catalog, but doesn't change these rules.
This means to access it, you fully qualify it with the class name: base::params::puppetserver. If you were using it in the manifest itself, this would be $base::params::puppetserver. You'll see similar examples in Pro Puppet in the ssh::config and ssh::service classes where it refers to "ssh_service_name" in the params class (pages 43-45).
To access the variable in a template it's a bit different, use scope.lookupvar("base::params::puppetserver"). Taking your full example and adding a missing equals sign (to output the value) in the template:
...
server=<%= scope.lookupvar("base::params::puppetserver") %>
There's a bit more information about scoping on the Scope and Puppet as of 2.7 page.
(Edit: looks like it's listed on the confirmed errata page too with the same solution.)
Answer #1 is technically correct, but results in very verbose templates.
You can shorten them by bringing variable values from other classes into your own class scope:
class base::config {
include base::params
$puppetserver = $base::params::puppetserver
...
}
And then use them in your template as expected:
server=<% puppetserver %>
You could also use inherits:
class puppet::config inherits puppet::params {
....
In this way you don't have to define $puppetserver again in this class.

Resources