Related
i have the result variable ( see at the bottom ) from a task (modul community.general.proxmox_kvm) and i want create a new dictionary variable from the items that changed in the result variable.
The structure should look like this
vm_dict:
80001:
host_name: ansible-clone1
host_ip_address: 10.10.0.1
80002:
host_name: ansible-clone2
host_ip_address: 10.10.0.2
What is a good way to accomplish this ? I tryed it with set_fact and combine filter but i get stucked and was not able to put multible values. Also the changed status not worked as expected.
- name: Populate dict
set_fact:
_dict: "{{ _dict|default({}) | combine( {item.item.key: item.item.value.host_name} ) }}"
loop: "{{ provisioning_vm.results }}"
when: provisioning_vm.changed == true
I will be happy for some suggestions.
Here is the result variable ( type list )
TASK [provisioning_proxmox : print var provisioning_vm] *************************************************************
ok: [localhost] => {
"provisioning_vm": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"acpi": null,
"agent": null,
"api_host": "10.0.10.1:8006",
"api_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"api_token_id": null,
"api_token_secret": null,
"api_user": "ansible_admin#pve",
"args": null,
"autostart": null,
"balloon": null,
"bios": null,
"boot": null,
"bootdisk": null,
"cicustom": null,
"cipassword": null,
"citype": null,
"ciuser": null,
"clone": "arbitrary_template",
"cores": null,
"cpu": null,
"cpulimit": null,
"cpuunits": null,
"delete": null,
"description": null,
"digest": null,
"efidisk0": null,
"force": null,
"format": "raw",
"freeze": null,
"full": true,
"hostpci": null,
"hotplug": null,
"hugepages": null,
"ide": null,
"ipconfig": null,
"keyboard": null,
"kvm": null,
"localtime": null,
"lock": null,
"machine": null,
"memory": null,
"migrate_downtime": null,
"migrate_speed": null,
"name": "ansible-clone1.dev.test.com",
"nameservers": null,
"net": null,
"newid": 80001,
"node": "proxmox01",
"numa": null,
"numa_enabled": null,
"onboot": null,
"ostype": null,
"parallel": null,
"pool": null,
"protection": null,
"proxmox_default_behavior": "no_defaults",
"reboot": null,
"revert": null,
"sata": null,
"scsi": null,
"scsihw": null,
"searchdomains": null,
"serial": null,
"shares": null,
"skiplock": null,
"smbios": null,
"snapname": null,
"sockets": null,
"sshkeys": null,
"startdate": null,
"startup": null,
"state": "present",
"storage": "CEPH-DEV",
"tablet": null,
"tags": null,
"target": null,
"tdf": null,
"template": null,
"timeout": 400,
"update": false,
"validate_certs": false,
"vcpus": null,
"vga": null,
"virtio": null,
"vmid": 987654,
"watchdog": null
}
},
"item": {
"key": 80001,
"value": {
"host_ip_address": "10.10.0.1",
"host_name": "ansible-clone1.dev.test.com"
}
},
"msg": "VM with name <ansible-clone1.dev.test.com> already exists",
"vmid": 80001
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"acpi": null,
"agent": null,
"api_host": "10.0.10.1:8006",
"api_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"api_token_id": null,
"api_token_secret": null,
"api_user": "ansible_admin#pve",
"args": null,
"autostart": null,
"balloon": null,
"bios": null,
"boot": null,
"bootdisk": null,
"cicustom": null,
"cipassword": null,
"citype": null,
"ciuser": null,
"clone": "arbitrary_template",
"cores": null,
"cpu": null,
"cpulimit": null,
"cpuunits": null,
"delete": null,
"description": null,
"digest": null,
"efidisk0": null,
"force": null,
"format": "raw",
"freeze": null,
"full": true,
"hostpci": null,
"hotplug": null,
"hugepages": null,
"ide": null,
"ipconfig": null,
"keyboard": null,
"kvm": null,
"localtime": null,
"lock": null,
"machine": null,
"memory": null,
"migrate_downtime": null,
"migrate_speed": null,
"name": "ansible-clone2.dev.test.com",
"nameservers": null,
"net": null,
"newid": 80002,
"node": "proxmox01",
"numa": null,
"numa_enabled": null,
"onboot": null,
"ostype": null,
"parallel": null,
"pool": null,
"protection": null,
"proxmox_default_behavior": "no_defaults",
"reboot": null,
"revert": null,
"sata": null,
"scsi": null,
"scsihw": null,
"searchdomains": null,
"serial": null,
"shares": null,
"skiplock": null,
"smbios": null,
"snapname": null,
"sockets": null,
"sshkeys": null,
"startdate": null,
"startup": null,
"state": "present",
"storage": "CEPH-DEV",
"tablet": null,
"tags": null,
"target": null,
"tdf": null,
"template": null,
"timeout": 400,
"update": false,
"validate_certs": false,
"vcpus": null,
"vga": null,
"virtio": null,
"vmid": 987654,
"watchdog": null
}
},
"item": {
"key": 80002,
"value": {
"host_ip_address": "10.10.0.2",
"host_name": "ansible-clone2.dev.test.com"
}
},
"msg": "VM with name <ansible-clone2.dev.test.com> already exists",
"vmid": 80002
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"acpi": null,
"agent": null,
"api_host": "10.0.10.1:8006",
"api_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"api_token_id": null,
"api_token_secret": null,
"api_user": "ansible_admin#pve",
"args": null,
"autostart": null,
"balloon": null,
"bios": null,
"boot": null,
"bootdisk": null,
"cicustom": null,
"cipassword": null,
"citype": null,
"ciuser": null,
"clone": "arbitrary_template",
"cores": null,
"cpu": null,
"cpulimit": null,
"cpuunits": null,
"delete": null,
"description": null,
"digest": null,
"efidisk0": null,
"force": null,
"format": "raw",
"freeze": null,
"full": true,
"hostpci": null,
"hotplug": null,
"hugepages": null,
"ide": null,
"ipconfig": null,
"keyboard": null,
"kvm": null,
"localtime": null,
"lock": null,
"machine": null,
"memory": null,
"migrate_downtime": null,
"migrate_speed": null,
"name": "ansible-clone4.dev.test.com",
"nameservers": null,
"net": null,
"newid": 80004,
"node": "proxmox01",
"numa": null,
"numa_enabled": null,
"onboot": null,
"ostype": null,
"parallel": null,
"pool": null,
"protection": null,
"proxmox_default_behavior": "no_defaults",
"reboot": null,
"revert": null,
"sata": null,
"scsi": null,
"scsihw": null,
"searchdomains": null,
"serial": null,
"shares": null,
"skiplock": null,
"smbios": null,
"snapname": null,
"sockets": null,
"sshkeys": null,
"startdate": null,
"startup": null,
"state": "present",
"storage": "CEPH-DEV",
"tablet": null,
"tags": null,
"target": null,
"tdf": null,
"template": null,
"timeout": 400,
"update": false,
"validate_certs": false,
"vcpus": null,
"vga": null,
"virtio": null,
"vmid": 987654,
"watchdog": null
}
},
"item": {
"key": 80004,
"value": {
"host_ip_address": "10.10.10.4",
"host_name": "ansible-clone4.dev.test.com"
}
},
"msg": "VM with name <ansible-clone4.dev.test.com> already exists",
"vmid": 80004
}
],
"skipped": false
}
}
For example,
vm_dict: "{{ dict(provisioning_vm.results|
json_query('[].[item.key, item.value]')) }}"
gives
vm_dict:
80001:
host_ip_address: 10.10.0.1
host_name: ansible-clone1.dev.test.com
80002:
host_ip_address: 10.10.0.2
host_name: ansible-clone2.dev.test.com
80004:
host_ip_address: 10.10.10.4
host_name: ansible-clone4.dev.test.com
Optionally, the task below rejects changed items. Change the filter to selectattr if you want to select them
vm_dict: "{{ dict(provisioning_vm.results|
rejectattr('changed')|
json_query('[].[item.key, item.value]')) }}"
I'm trying to generate flate type script class using nswag
I belive there's a proprty 'flattenInheritanceHierarchy' that can do what i need. but seems like its not working. not sure what i'm missing.
I have a c# class called Result which is inheriting from Result
public partial record Result
{
public bool IsSucceeded { get; set; }
public string Message { get; set; } = string.Empty;
}
public partial record Result<T> : Result where T : new()
{
public T Value { get; set; } = new T();
}
i'm using it to retunr the result like this
public async Task<IActionResult> Create(CarDto dto)
{
return Ok(new Result<CarDto>());
}
when i generate typescript classes, actual result is
export class Result {
isSucceeded!: boolean;
message!: string;
}
export class ResultOfCarDto extends Result {
value!: CarDto;
}
but i want it like
export class ResultOfCarDto {
isSucceeded!: boolean;
message!: string;
value!: CarDto;
}
here's my nswag.json
{
"runtime": "Net60",
"defaultVariables": null,
"documentGenerator": {
"aspNetCoreToOpenApi": {
"project": "Web.csproj",
"msBuildProjectExtensionsPath": null,
"configuration": null,
"runtime": null,
"targetFramework": null,
"noBuild": true,
"verbose": false,
"workingDirectory": null,
"requireParametersWithoutDefault": true,
"apiGroupNames": null,
"defaultPropertyNameHandling": "CamelCase",
"defaultReferenceTypeNullHandling": "Null",
"defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
"defaultResponseReferenceTypeNullHandling": "NotNull",
"defaultEnumHandling": "Integer",
"flattenInheritanceHierarchy": true,
"generateKnownTypes": true,
"generateEnumMappingDescription": true,
"generateXmlObjects": false,
"generateAbstractProperties": false,
"generateAbstractSchemas": true,
"ignoreObsoleteProperties": true,
"allowReferencesWithProperties": false,
"excludedTypeNames": [],
"serviceHost": null,
"serviceBasePath": null,
"serviceSchemes": [],
"infoTitle": "API",
"infoDescription": null,
"infoVersion": "1.0.0",
"documentTemplate": null,
"documentProcessorTypes": [],
"operationProcessorTypes": [],
"typeNameGeneratorType": null,
"schemaNameGeneratorType": null,
"contractResolverType": null,
"serializerSettingsType": null,
"useDocumentProvider": true,
"documentName": "v1",
"aspNetCoreEnvironment": null,
"createWebHostBuilderMethod": null,
"startupType": null,
"allowNullableBodyParameters": false,
"output": "wwwroot/api/specification.json",
"outputType": "OpenApi3",
"assemblyPaths": [],
"assemblyConfig": null,
"referencePaths": [],
"useNuGetCache": false
}
},
"codeGenerators": {
"openApiToTypeScriptClient": {
"className": "{controller}Client",
"moduleName": "",
"namespace": "",
"typeScriptVersion": 4.3,
"template": "Angular",
"promiseType": "Promise",
"httpClass": "HttpClient",
"withCredentials": false,
"useSingletonProvider": true,
"injectionTokenType": "InjectionToken",
"rxJsVersion": 6.0,
"dateTimeType": "Date",
"nullValue": "Undefined",
"generateClientClasses": false,
"generateClientInterfaces": false,
"generateOptionalParameters": false,
"exportTypes": true,
"wrapDtoExceptions": false,
"exceptionClass": "SwaggerException",
"clientBaseClass": null,
"wrapResponses": false,
"wrapResponseMethods": [],
"generateResponseClasses": true,
"responseClass": "SwaggerResponse",
"protectedMethods": [],
"configurationClass": null,
"useTransformOptionsMethod": false,
"useTransformResultMethod": false,
"flattenInheritanceHierarchy": false,
"generateDtoTypes": true,
"operationGenerationMode": "MultipleClientsFromOperationId",
"markOptionalProperties": false,
"generateCloneMethod": false,
"typeStyle": "Class",
"enumStyle": "Enum",
"useLeafType": true,
"classTypes": [],
"extendedClasses": [],
"extensionCode": null,
"generateDefaultValues": true,
"generateAbstractProperties": false,
"generateAbstractSchemas": false,
"ignoreObsoleteProperties": true,
"excludedTypeNames": [],
"excludedParameterNames": [],
"includeHttpContext": false,
"handleReferences": false,
"generateTypeCheckFunctions": false,
"generateConstructorInterface": false,
"convertConstructorInterfaceData": false,
"importRequiredTypes": true,
"useGetBaseUrlMethod": false,
"baseUrlTokenName": "API_BASE_URL",
"queryNullValue": "",
"inlineNamedDictionaries": false,
"inlineNamedAny": false,
"templateDirectory": null,
"typeNameGeneratorType": null,
"propertyNameGeneratorType": null,
"enumNameGeneratorType": null,
"serviceHost": null,
"serviceSchemes": null,
"output": "ClientApp/src/app/dto/api-dtos.ts"
}
}
}
addtionally its generating 3 fromJS, init and toJSON functions which i also dont want
export class StatusCountDto {
count!: number;
status!: string;
#region I dont want to generate this
init(_data?: any) {
if (_data) {
this.count = _data["count"];
this.status = _data["status"];
}
}
static fromJS(data: any): IssueCountDto {
data = typeof data === 'object' ? data : {};
let result = new IssueCountDto();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["count"] = this.count;
data["status"] = this.status;
return data;
}
#endregion I dont want to generate this
}
any suggesstion?
I've done a mapping before, but not this deeply nested. I am trying to re-populate data from a corrupt db. I have manually reconstructed an orders array. I'm trying to look up data for each player, and then update the fields (which start out null) for each player:
Example: I start with data like this:
const orders = [
{
"paymentID": "ch_456",
"paymentStatus": "PAID",
"user": "kingkong#gmail.com",
"cart": {
"username": "kingkong#gmail.com",
"totalQty": 1,
"totalPrice": 80,
"items": [{
"event": "Men's BB",
"division": "Men's",
"level": "BB",
"group": "nonpro",
"field": "PAL",
"day": "Saturday",
"numplayers": 2,
"price": 80,
"players": [{
"avp_id": 1042641,
"first": "King",
"last": "Kong",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false},
{
"avp_id": 1086117,
"first": "Jacob",
"last": "Ladder",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false,
"shirt_size": "N/A"}],
"net": null,
"team": null,
"notes": null,
"paymentNote": null,
"waiversSent": false,
"active": true,
"paymentID": "ch_456",
"users": ["kingkong#gmail.com"],
"paymentStatus": "PAID", "__v": 4}]},
"__v": 0
},{
"paymentID": "ch_123",
"paymentStatus": "PAID",
"user": "marymac#aol.com",
"cart": {
"username": "marymac#aol.com",
"totalQty": 1,
"totalPrice": 50,
"items": [{
"event": "Junior Boys 16s",
"division": "Junior Boys",
"level": "16s",
"group": "nonpro",
"field": "Main",
"day": "Friday",
"numplayers": 2,
"price": 80,
"players": [{
"avp_id": 1022228,
"first": "Some",
"last": "Kid",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false
}, {
"avp_id": 1020142,
"first": "Justin",
"last": "Kid",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false,
"shirt_size": "N/A"
}
],
"net": null,
"team": null,
"notes": null,
"paymentNote": null,
"waiversSent": false,
"active": true,
"paymentID": "ch_123",
"users": ["marymac#aol.com"],
"paymentStatus": "PAID", "__v": 4
}
]
},
"__v": 0
}];
Here is my code, which I'd like to get the data from an API, and update player info to pass into a function further down:
async getLostData() {
// get the lost orders
console.log('start lost data import');
// this.adminService.GetLostOrders().subscribe(orders => {
// console.log('load each order into system', orders);
orders.forEach(order => {
order.cart.items.map(item => {
const players = item.players.map(async player => {
player = await
this.adminService.adminAVPReg(player.last, player.avp_id)
.toPromise();
console.log("updated player outside subscribe", player);
});
item.players = players;
console.log("item", item);
});
// load order with updated info, create registration, and skip pmt
// this.adminService.LoadLostOrders(order).subscribe(data => {
// console.log(data);
// console.log('finished');
// });
});
console.log("orderlist", orders);
// });}
The data I'm getting logged is interesting. What comes back first from the logger is each item, followed by orderlist, and then the updated player info. Each item shows the players array listed as ZoneAwarePromise. I have no idea how to replace that with the actual data, but I can see it's not being logged in the order I expected.
How can I get the item to return with the updated data?
From what I understood you are trying to do, I came up with this,
this.adminService.GetLostOrders().pipe(
mergeMap((orders: any[]) => from(orders).pipe(
mergeMap((order) => from(order.cart.items)),
mergeMap((item) => of(item).pipe(
mergeMap(_ => from(item.players)),
mergeMap(player => this.adminService.adminAVPReg(player.last, player.avp_id).pipe(
map(newPlayer => { player = newPlayer; return player; }))
),
toArray(),
tap(newPlayerArray => item.players = newPlayerArray)
)),
toArray(),
mergeMap(_ => this.adminService.LoadLostOrders(orders))
))
).subscribe();
OP's Edit
I implemented what you shared above, and turned it into this:
getLostData() {
// get the lost orders
console.log('start lost data import');
// get manually created orders from lostdata collection
this.adminService.GetLostOrders()
.pipe(
mergeMap((orders: any) => from(orders).pipe(
mergeMap((order: any) => from(order.cart.items)),
mergeMap((item: any) => of(item).pipe(
mergeMap(_ => from(item.players)),
mergeMap((player: any) => this.adminService.adminAVPReg(player.last, player.avp_id).pipe(
map((newPlayer: any) => {
player.avp_id = player.avp_id;
player.signed = player.signed;
player.waivers = player.waivers;
player.country = player.country;
player.completed = true;
player.sandbagger = false;
player.first = newPlayer.first;
player.last = newPlayer.last;
player.email = newPlayer.email;
player.address = newPlayer.address;
player.city = newPlayer.city;
player.state = newPlayer.state;
player.zip = newPlayer.zip;
player.shirt_size = newPlayer.shirt_size;
player.ranking = newPlayer.ranking;
player.overallRanking = newPlayer.overallRanking;
player.notes = player.notes;
player.phone = newPlayer.phone;
player.adult = newPlayer.adult;
return player; }))
),
toArray(),
tap(newPlayerArray => item.players = newPlayerArray)
)),
toArray(),
tap(_ => { this.loadlostOrders(orders);
})
))
)
.subscribe();
}
loadlostOrders(orders) {
orders.forEach(order => {
this.adminService.LoadLostOrders(order).subscribe((data) => {
console.log("success", JSON.stringify(data));
}, (error) => {
console.log("error", JSON.stringify(error));
});
});
}
Opening http://mycloud/dashboard
I got
http://mycloud/dashboard/auth/login/?next=/dashboard/
After auth succed, I got
http://mycloud/dashboard/project/
Try to click on 'API Access', I'm thrown back to login page
http://mycloud/dashboard/auth/login/?next=/dashboard/project/api_access/
Basically, anywhere I click I always back to login page.
Below is my openstack_dashboard/local/local_settings.py
import os
from django.utils.translation import ugettext_lazy as _
from horizon.utils import secret_key
from openstack_dashboard.settings import HORIZON_CONFIG
DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'horizon',
'USER': 'packstack',
'PASSWORD': 'L3tM31n',
'HOST': '192.168.5.80',
'PORT': '5432',
}
}
COMPRESS_OFFLINE = True
SESSION_TIMEOUT = 1800
WEBROOT = '/dashboard/'
LOGIN_URL = WEBROOT + 'auth/login/'
LOGOUT_URL = WEBROOT + 'auth/logout/'
LOGIN_REDIRECT_URL = WEBROOT
ALLOWED_HOSTS = ['*']
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))
SECRET_KEY = secret_key.generate_or_read_from_file(
os.path.join(LOCAL_PATH, '.secret_key_store'))
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
CACHES = {
'default':{
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': '127.0.0.1:11211',
},
}
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
OPENSTACK_HOST = "127.0.0.1"
OPENSTACK_KEYSTONE_URL = "http://%s:7001/v3" % OPENSTACK_HOST
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"
OPENSTACK_KEYSTONE_BACKEND = {
'name': 'native',
'can_edit_user': True,
'can_edit_group': True,
'can_edit_project': True,
'can_edit_domain': True,
'can_edit_role': True,
}
OPENSTACK_HYPERVISOR_FEATURES = {
'can_set_mount_point': False,
'can_set_password': False,
'requires_keypair': False,
'enable_quotas': True
}
OPENSTACK_CINDER_FEATURES = {
'enable_backup': False,
}
OPENSTACK_NEUTRON_NETWORK = {
'enable_router': True,
'enable_quotas': True,
'enable_ipv6': True,
'enable_distributed_router': False,
'enable_ha_router': False,
'enable_fip_topology_check': True,
'supported_vnic_types': ['*'],
'physical_networks': [],
}
OPENSTACK_HEAT_STACK = {
'enable_user_pass': True,
}
IMAGE_CUSTOM_PROPERTY_TITLES = {
"architecture": _("Architecture"),
"kernel_id": _("Kernel ID"),
"ramdisk_id": _("Ramdisk ID"),
"image_state": _("Euca2ools state"),
"project_id": _("Project ID"),
"image_type": _("Image Type"),
}
IMAGE_RESERVED_CUSTOM_PROPERTIES = []
API_RESULT_LIMIT = 1000
API_RESULT_PAGE_SIZE = 20
SWIFT_FILE_TRANSFER_CHUNK_SIZE = 512 * 1024
INSTANCE_LOG_LENGTH = 35
DROPDOWN_MAX_ITEMS = 30
TIME_ZONE = "UTC"
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'console': {
'format': '%(levelname)s %(name)s %(message)s'
},
'operation': {
'format': '%(message)s'
},
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'console',
},
'operation': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'operation',
},
},
'loggers': {
'horizon': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'horizon.operation_log': {
'handlers': ['operation'],
'level': 'INFO',
'propagate': False,
},
'openstack_dashboard': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'novaclient': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'cinderclient': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'keystoneauth': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'keystoneclient': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'glanceclient': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'neutronclient': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'swiftclient': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'oslo_policy': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'openstack_auth': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'django': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'django.db.backends': {
'handlers': ['null'],
'propagate': False,
},
'requests': {
'handlers': ['null'],
'propagate': False,
},
'urllib3': {
'handlers': ['null'],
'propagate': False,
},
'chardet.charsetprober': {
'handlers': ['null'],
'propagate': False,
},
'iso8601': {
'handlers': ['null'],
'propagate': False,
},
'scss': {
'handlers': ['null'],
'propagate': False,
},
},
}
SECURITY_GROUP_RULES = {
'all_tcp': {
'name': _('All TCP'),
'ip_protocol': 'tcp',
'from_port': '1',
'to_port': '65535',
},
'all_udp': {
'name': _('All UDP'),
'ip_protocol': 'udp',
'from_port': '1',
'to_port': '65535',
},
'all_icmp': {
'name': _('All ICMP'),
'ip_protocol': 'icmp',
'from_port': '-1',
'to_port': '-1',
},
'ssh': {
'name': 'SSH',
'ip_protocol': 'tcp',
'from_port': '22',
'to_port': '22',
},
'smtp': {
'name': 'SMTP',
'ip_protocol': 'tcp',
'from_port': '25',
'to_port': '25',
},
'dns': {
'name': 'DNS',
'ip_protocol': 'tcp',
'from_port': '53',
'to_port': '53',
},
'http': {
'name': 'HTTP',
'ip_protocol': 'tcp',
'from_port': '80',
'to_port': '80',
},
'pop3': {
'name': 'POP3',
'ip_protocol': 'tcp',
'from_port': '110',
'to_port': '110',
},
'imap': {
'name': 'IMAP',
'ip_protocol': 'tcp',
'from_port': '143',
'to_port': '143',
},
'ldap': {
'name': 'LDAP',
'ip_protocol': 'tcp',
'from_port': '389',
'to_port': '389',
},
'https': {
'name': 'HTTPS',
'ip_protocol': 'tcp',
'from_port': '443',
'to_port': '443',
},
'smtps': {
'name': 'SMTPS',
'ip_protocol': 'tcp',
'from_port': '465',
'to_port': '465',
},
'imaps': {
'name': 'IMAPS',
'ip_protocol': 'tcp',
'from_port': '993',
'to_port': '993',
},
'pop3s': {
'name': 'POP3S',
'ip_protocol': 'tcp',
'from_port': '995',
'to_port': '995',
},
'ms_sql': {
'name': 'MS SQL',
'ip_protocol': 'tcp',
'from_port': '1433',
'to_port': '1433',
},
'mysql': {
'name': 'MYSQL',
'ip_protocol': 'tcp',
'from_port': '3306',
'to_port': '3306',
},
'rdp': {
'name': 'RDP',
'ip_protocol': 'tcp',
'from_port': '3389',
'to_port': '3389',
},
}
REST_API_REQUIRED_SETTINGS = ['OPENSTACK_HYPERVISOR_FEATURES',
'LAUNCH_INSTANCE_DEFAULTS',
'OPENSTACK_IMAGE_FORMATS',
'OPENSTACK_KEYSTONE_BACKEND',
'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN',
'CREATE_IMAGE_DEFAULTS',
'ENFORCE_PASSWORD_CHECK']
ALLOWED_PRIVATE_SUBNET_CIDR = {'ipv4': [], 'ipv6': []}
LOGIN_REDIRECT_URL = WEBROOT
MEDIA_URL = WEBROOT + '/media/'
STATIC_URL = WEBROOT + '/static/'
I fill grid by ashx file and its work fine.
When i add action in grid ,data of cell shift to right and last column show Null.
Before add Action
After add Action
grid in firebug:
ashx:
public void ProcessRequest(HttpContext context) {
HttpRequest request = context.Request;
HttpResponse response = context.Response;
string _search = request["_search"];
string numberOfRows = request["rows"];
string pageIndex = request["page"];
string sortColumnName = request["sidx"];
string sortOrderBy = request["sord"];
int totalRecords;
Collection<User> users = GetDummyUsers(numberOfRows, pageIndex, sortColumnName, sortOrderBy, out totalRecords);
string output = BuildJQGridResults (users, Convert.ToInt32 (numberOfRows), Convert.ToInt32 (pageIndex), Convert.ToInt32 (totalRecords));
response.Write (output);
}
Create Users:
private Collection<User> GetDummyUsers(string numberOfRows, string pageIndex, string sortColumnName, string sortOrderBy, out int totalRecords) {
var data = new Collection<User> {
new User(){ UserID = 1,UserName = "Bill Gates", FirstName = "Bill", LastName = "Gates",EmailID = "test#microsoft.com", },
new User(){ UserID = 1,UserName = "Bill Gates", FirstName = "Bill", LastName = "Gates",EmailID = "test#microsoft.com", },
new User(){ UserID = 1,UserName = "Bill Gates", FirstName = "Bill", LastName = "Gates",EmailID = "test#microsoft.com", },
};
totalRecords = data.Count;
return data;
}
ConvetTo json:
private string BuildJQGridResults(Collection<User> users, int numberOfRows, int pageIndex, int totalRecords) {
JQGridResults result = new JQGridResults ();
List<JQGridRow> rows = new List<JQGridRow> ();
foreach (User user in users) {
JQGridRow row = new JQGridRow ();
row.id = user.UserID;
row.cell = new string[5];
row.cell[0] = user.UserID.ToString ();
row.cell[1] = user.UserName;
row.cell[2] = user.FirstName;
row.cell[3] = user.LastName;
row.cell[4] = user.EmailID;
rows.Add (row);
}
result.rows = rows.ToArray ();
result.page = pageIndex;
result.total = (totalRecords + numberOfRows - 1) / numberOfRows;
result.records = totalRecords;
return new JavaScriptSerializer ().Serialize (result);
}
grid:
url: 'jqGridHandler.ashx',
datatype: 'json',
autowidth: true,
height: 100,
colNames: ['ACTION', 'ID', 'UserName', 'FirstName', 'LastName', 'EmailID'],
colModel: [
{
name: 'act', width: 100, align: 'center', sortable: false, formatter: 'actions',
formatoptions: {
keys: true,
delOptions: true,
delbutton:true,
editbutton:false
}
},
{ name: 'UserID', width: 100, sortable: true, },
{ name: 'UserName', width: 100, sortable: true },
{ name: 'FirstName', width: 100, sortable: true },
{ name: 'LastName', width: 100, sortable: true },
{ name: 'EmailID', width: 100, sortable: true },
],
rowNum: 20,
loadonce: true,
rowList: [5, 10, 20],
recordpos: "left",
ignoreCase: true,
toppager: true,
viewrecords: true,
sortorder: "desc",
scrollOffset: 1,
});
});
jqGrid is treating actions as real column and it expects data for it. The easiest way out of this is to add empty cell to your row on server side:
private string BuildJQGridResults(Collection<User> users, int numberOfRows, int pageIndex, int totalRecords) {
JQGridResults result = new JQGridResults ();
List<JQGridRow> rows = new List<JQGridRow> ();
foreach (User user in users) {
JQGridRow row = new JQGridRow ();
row.id = user.UserID;
row.cell = new string[6];
row.cell[0] = String.Empty;
row.cell[1] = user.UserID.ToString ();
row.cell[2] = user.UserName;
row.cell[3] = user.FirstName;
row.cell[4] = user.LastName;
row.cell[5] = user.EmailID;
rows.Add (row);
}
result.rows = rows.ToArray ();
result.page = pageIndex;
result.total = (totalRecords + numberOfRows - 1) / numberOfRows;
result.records = totalRecords;
return new JavaScriptSerializer ().Serialize (result);
}
As an alternative you can use jqGrid in repeatItems: false mode. First you need to change the jqGrid initialization script:
$("#UsersGrid").jqGrid({
url: 'jqGridHandler.ashx',
datatype: 'json',
autowidth: true,
height: 100,
colNames: ['ACTION', 'ID', 'UserName', 'FirstName', 'LastName', 'EmailID'],
colModel: [
{ name: 'act', width: 100, align: 'center', sortable: false, formatter: 'actions', formatoptions: { keys: true, delOptions: true, delbutton:true, editbutton:false } },
{ name: 'UserID', width: 100, sortable: true, },
{ name: 'UserName', width: 100, sortable: true },
{ name: 'FirstName', width: 100, sortable: true },
{ name: 'LastName', width: 100, sortable: true },
{ name: 'EmailID', width: 100, sortable: true },
],
rowNum: 20,
loadonce: true,
rowList: [5, 10, 20],
recordpos: 'left',
ignoreCase: true,
toppager: true,
viewrecords: true,
sortorder: 'desc',
scrollOffset: 1,
jsonReader : {
repeatitems: false
}
});
Now on server side you can no longer use array, you have to use object or dictionary. I will show the more generic approach which is dictionary. Assuming your solution is based on this sample, you will have to change JQGridResult class like this:
public class JQGridResults
{
public int page;
public int total;
public int records;
public List<Dictionary<string, string>> rows;
}
Now your method can look like this:
private string BuildJQGridResults(Collection<User> users, int numberOfRows, int pageIndex, int totalRecords) {
JQGridResults result = new JQGridResults();
result.rows = new List<Dictionary<string, string>>();
foreach (User user in users) {
Dictionary<string, string> row = new Dictionary<string, string>();
row.Add("id", user.UserID.ToString());
row.Add("UserID", user.UserID.ToString());
row.Add("UserName", user.UserName);
row.Add("FirstName", user.FirstName);
row.Add("LastName", user.LastName);
row.Add("EmailID", user.EmailID);
result.rows.Add(row);
}
result.page = pageIndex;
result.total = (totalRecords + numberOfRows - 1) / numberOfRows;
result.records = totalRecords;
return new JavaScriptSerializer().Serialize(result);
}
This can be further optimized to avoid sending UserId twice, but this is not what is important from your question point of view.
Code works completely fine in my browser. Try with this code. Hopw it works also just check in your webdeveloper tools are you getting any error there.
Also paste your code for myDelOptions.
$("#datagrid").jqGrid({
url: 'jqGridHandler.ashx',
datatype: 'json',
autowidth: true,
height: 100,
colNames: [ 'ACTION', 'EOSysNum', 'PctIndNum', 'PctLettSubject', 'PctAssignSubject', ],
colModel: [
{
name: 'act', width: 100, align: 'center', sortable: false, formatter: 'actions',
formatoptions: {
keys: true,
delOptions: true,
delbutton:true,
editbutton:false
}
},
{ name: 'EOSysNum', index: 'UserID', width: 50, sortable: true, hidden: false },
{ name: 'PctIndNum', width: 140, sortable: true },
{ name: 'PctLettSubject', width: 140, sortable: true },
{ name: 'PctAssignSubject', width: 100, sortable: true },
],
rowNum: 20,
loadonce: true,
rowList: [5, 10, 20],
recordpos: "left",
ignoreCase: true,
toppager: true,
viewrecords: true,
sortorder: "desc",
scrollOffset: 1,
});
remove direction option from jqgrid and let us know it works or not