Showing preview only (7,830K chars total). Download the full file or copy to clipboard to get everything.
Repository: pritunl/pritunl-cloud
Branch: master
Commit: e75523642c38
Files: 1089
Total size: 7.3 MB
Directory structure:
gitextract_pa6e1wrf/
├── .gitattributes
├── .gitignore
├── CHANGES
├── LICENSE
├── README.md
├── acme/
│ ├── acme.go
│ ├── challenge.go
│ ├── constants.go
│ └── utils.go
├── advisory/
│ ├── advisory.go
│ ├── constants.go
│ └── utils.go
├── agent/
│ ├── agent.go
│ ├── constants/
│ │ └── constants.go
│ ├── imds/
│ │ ├── imds.go
│ │ ├── journal.go
│ │ ├── sync.go
│ │ └── utils.go
│ ├── logging/
│ │ ├── file.go
│ │ ├── handler.go
│ │ ├── logging.go
│ │ └── systemd.go
│ └── utils/
│ ├── sanitize.go
│ └── sys.go
├── aggregate/
│ ├── block.go
│ ├── deployment.go
│ ├── disk.go
│ ├── domain.go
│ ├── instance.go
│ ├── pod.go
│ └── shape.go
├── ahandlers/
│ ├── alert.go
│ ├── audit.go
│ ├── auth.go
│ ├── authority.go
│ ├── balancer.go
│ ├── block.go
│ ├── certificate.go
│ ├── check.go
│ ├── completion.go
│ ├── csrf.go
│ ├── datacenter.go
│ ├── devices.go
│ ├── disk.go
│ ├── domain.go
│ ├── event.go
│ ├── firewall.go
│ ├── handlers.go
│ ├── image.go
│ ├── instance.go
│ ├── license.go
│ ├── log.go
│ ├── node.go
│ ├── organization.go
│ ├── plan.go
│ ├── pod.go
│ ├── policy.go
│ ├── pool.go
│ ├── relations.go
│ ├── secret.go
│ ├── session.go
│ ├── settings.go
│ ├── shape.go
│ ├── static.go
│ ├── storage.go
│ ├── subscription.go
│ ├── theme.go
│ ├── user.go
│ ├── vpc.go
│ └── zone.go
├── alert/
│ ├── alert.go
│ ├── constants.go
│ └── utils.go
├── alertevent/
│ ├── alertevent.go
│ └── utils.go
├── arp/
│ └── arp.go
├── audit/
│ ├── audit.go
│ ├── constants.go
│ └── utils.go
├── auth/
│ ├── auth.go
│ ├── authzero.go
│ ├── azure.go
│ ├── constants.go
│ ├── errortypes.go
│ ├── google.go
│ ├── handler.go
│ ├── jumpcloud.go
│ ├── saml.go
│ ├── state.go
│ ├── sync.go
│ └── utils.go
├── authority/
│ ├── authority.go
│ ├── constants.go
│ └── utils.go
├── authorizer/
│ ├── authorizer.go
│ ├── constants.go
│ └── utils.go
├── backup/
│ └── backup.go
├── balancer/
│ ├── balancer.go
│ ├── constants.go
│ └── utils.go
├── block/
│ ├── block.go
│ ├── constants.go
│ ├── errortypes.go
│ ├── ip.go
│ └── utils.go
├── bridges/
│ └── bridges.go
├── certificate/
│ ├── certificate.go
│ ├── constants.go
│ └── utils.go
├── cloud/
│ ├── cloud.go
│ └── oracle.go
├── cloudinit/
│ ├── cloudinit.go
│ ├── query.go
│ └── utils.go
├── cmd/
│ ├── backup.go
│ ├── dhcp.go
│ ├── imds.go
│ ├── instance.go
│ ├── log.go
│ ├── mtu.go
│ ├── node.go
│ ├── optimize.go
│ └── settings.go
├── colorize/
│ └── colorize.go
├── completion/
│ └── completion.go
├── compositor/
│ └── compositor.go
├── config/
│ └── config.go
├── constants/
│ └── constants.go
├── cookie/
│ ├── cookie.go
│ └── utils.go
├── crypto/
│ └── crypto.go
├── csrf/
│ └── csrf.go
├── data/
│ ├── disk.go
│ ├── image.go
│ ├── resize.go
│ ├── sync.go
│ └── utils.go
├── database/
│ ├── base.go
│ ├── client.go
│ ├── collection.go
│ ├── database.go
│ ├── errors.go
│ ├── index.go
│ └── utils.go
├── datacenter/
│ ├── constants.go
│ ├── datacenter.go
│ └── utils.go
├── defaults/
│ └── defaults.go
├── demo/
│ ├── alert.go
│ ├── authority.go
│ ├── balancer.go
│ ├── block.go
│ ├── certificate.go
│ ├── datacenter.go
│ ├── demo.go
│ ├── disk.go
│ ├── domain.go
│ ├── firewall.go
│ ├── instance.go
│ ├── log.go
│ ├── node.go
│ ├── organization.go
│ ├── plan.go
│ ├── pod.go
│ ├── policy.go
│ ├── pool.go
│ ├── rand.go
│ ├── secret.go
│ ├── shape.go
│ ├── storage.go
│ ├── subscription.go
│ ├── user.go
│ ├── vpc.go
│ └── zone.go
├── deploy/
│ ├── deploy.go
│ ├── deployments.go
│ ├── disks.go
│ ├── imds.go
│ ├── instances.go
│ ├── ipset.go
│ ├── iptables.go
│ ├── namespace.go
│ ├── network.go
│ └── services.go
├── deployment/
│ ├── constants.go
│ ├── deployment.go
│ └── utils.go
├── device/
│ ├── constants.go
│ ├── device.go
│ ├── facet.go
│ └── utils.go
├── dhcpc/
│ ├── constants.go
│ ├── dhcpc.go
│ ├── imds.go
│ ├── lease.go
│ ├── lease4.go
│ ├── lease6.go
│ ├── systemd.go
│ └── utils.go
├── dhcps/
│ ├── dhcp4.go
│ ├── dhcp6.go
│ ├── ndp.go
│ └── systemd.go
├── disk/
│ ├── constants.go
│ ├── disk.go
│ ├── sort.go
│ └── utils.go
├── dns/
│ ├── aws.go
│ ├── cloudflare.go
│ ├── constants.go
│ ├── dns.go
│ ├── errors.go
│ ├── google.go
│ ├── oracle.go
│ └── utils.go
├── dnss/
│ ├── constants.go
│ ├── database.go
│ ├── dnss.go
│ ├── plugin.go
│ └── response.go
├── domain/
│ ├── constants.go
│ ├── domain.go
│ ├── record.go
│ ├── sort.go
│ └── utils.go
├── drive/
│ ├── drive.go
│ └── utils.go
├── engine/
│ ├── bash.go
│ ├── constants.go
│ ├── engine.go
│ ├── parser.go
│ └── python.go
├── errortypes/
│ └── errortypes.go
├── eval/
│ ├── constants.go
│ ├── errortypes.go
│ ├── eval.go
│ └── utils.go
├── event/
│ ├── event.go
│ ├── listener.go
│ └── socket.go
├── features/
│ ├── qemu.go
│ └── systemd.go
├── finder/
│ ├── constants.go
│ └── resources.go
├── firewall/
│ ├── constants.go
│ ├── firewall.go
│ ├── spec.go
│ └── utils.go
├── geo/
│ └── geo.go
├── go.mod
├── go.sum
├── guest/
│ ├── guest.go
│ └── power.go
├── hnetwork/
│ ├── hnetwork.go
│ └── utils.go
├── hugepages/
│ └── hugepages.go
├── image/
│ ├── constants.go
│ ├── errortypes.go
│ ├── image.go
│ ├── sort.go
│ └── utils.go
├── imds/
│ ├── config.go
│ ├── imds.go
│ ├── resource/
│ │ ├── resource.go
│ │ └── utils.go
│ ├── server/
│ │ ├── config/
│ │ │ └── config.go
│ │ ├── constants/
│ │ │ └── constants.go
│ │ ├── errortypes/
│ │ │ └── errortypes.go
│ │ ├── handlers/
│ │ │ ├── certificate.go
│ │ │ ├── dhcp.go
│ │ │ ├── handlers.go
│ │ │ ├── instance.go
│ │ │ ├── node.go
│ │ │ ├── query.go
│ │ │ ├── secret.go
│ │ │ ├── sync.go
│ │ │ └── vpc.go
│ │ ├── router/
│ │ │ └── router.go
│ │ ├── server.go
│ │ ├── state/
│ │ │ └── state.go
│ │ └── utils/
│ │ ├── files.go
│ │ ├── misc.go
│ │ └── request.go
│ ├── systemd.go
│ └── types/
│ ├── certificate.go
│ ├── config.go
│ ├── constants.go
│ ├── domain.go
│ ├── instance.go
│ ├── journal.go
│ ├── node.go
│ ├── pod.go
│ ├── secret.go
│ ├── state.go
│ └── vpc.go
├── info/
│ └── instance.go
├── instance/
│ ├── constants.go
│ ├── errortypes.go
│ ├── instance.go
│ └── utils.go
├── interfaces/
│ └── interfaces.go
├── ip/
│ ├── interface.go
│ └── ip.go
├── iproute/
│ ├── address.go
│ ├── bridge.go
│ └── iface.go
├── ipset/
│ ├── names.go
│ ├── sets.go
│ ├── state.go
│ └── utils.go
├── iptables/
│ ├── iptables.go
│ ├── lock.go
│ ├── rules.go
│ ├── state.go
│ ├── update.go
│ └── utils.go
├── ipvs/
│ ├── constants.go
│ ├── ipvs.go
│ ├── service.go
│ └── target.go
├── iscsi/
│ └── iscsi.go
├── iso/
│ └── iso.go
├── journal/
│ ├── constants.go
│ ├── journal.go
│ ├── store.go
│ └── utils.go
├── lock/
│ └── lvm.go
├── log/
│ ├── constants.go
│ ├── log.go
│ └── utils.go
├── logger/
│ ├── database.go
│ ├── file.go
│ ├── formatter.go
│ ├── hook.go
│ ├── limiter.go
│ ├── logger.go
│ ├── sender.go
│ └── writer.go
├── lvm/
│ ├── lv.go
│ └── vgs.go
├── main.go
├── middlewear/
│ ├── gzip.go
│ └── middlewear.go
├── mtu/
│ └── mtu.go
├── netconf/
│ ├── address.go
│ ├── base.go
│ ├── bridge.go
│ ├── clear.go
│ ├── external.go
│ ├── host.go
│ ├── iface.go
│ ├── imds.go
│ ├── internal.go
│ ├── ip.go
│ ├── netconf.go
│ ├── nodeport.go
│ ├── oracle.go
│ ├── space.go
│ ├── utils.go
│ ├── validate.go
│ └── vlan.go
├── node/
│ ├── block.go
│ ├── certificate.go
│ ├── constants.go
│ ├── interfaces.go
│ ├── node.go
│ ├── oracle.go
│ └── utils.go
├── nodeport/
│ ├── constants.go
│ ├── mapping.go
│ ├── network.go
│ ├── nodeport.go
│ └── utils.go
├── nonce/
│ └── nonce.go
├── notification/
│ └── notification.go
├── oracle/
│ ├── iface.go
│ ├── metadata.go
│ ├── oracle.go
│ ├── provider.go
│ ├── routetable.go
│ ├── subnet.go
│ ├── utils.go
│ └── vnic.go
├── organization/
│ ├── organization.go
│ └── utils.go
├── paths/
│ ├── paths.go
│ └── utils.go
├── pci/
│ ├── pci.go
│ └── utils.go
├── permission/
│ ├── permission.go
│ └── user.go
├── plan/
│ ├── constants.go
│ ├── data.go
│ ├── plan.go
│ └── utils.go
├── planner/
│ ├── planner.go
│ └── utils.go
├── pod/
│ ├── pod.go
│ └── utils.go
├── policy/
│ ├── constants.go
│ ├── policy.go
│ └── utils.go
├── pool/
│ ├── constants.go
│ ├── pool.go
│ └── utils.go
├── proxy/
│ ├── constants.go
│ ├── domain.go
│ ├── errortypes.go
│ ├── proxy.go
│ ├── resolver.go
│ ├── reverse.go
│ ├── transport.go
│ ├── types.go
│ ├── utils.go
│ └── ws.go
├── qemu/
│ ├── constants.go
│ ├── data.go
│ ├── disk.go
│ ├── manage.go
│ ├── network.go
│ ├── power.go
│ ├── qemu.go
│ ├── routes.go
│ ├── sort.go
│ ├── usb.go
│ └── utils.go
├── qga/
│ └── qga.go
├── qmp/
│ ├── backup.go
│ ├── disk.go
│ ├── errors.go
│ ├── password.go
│ ├── power.go
│ ├── qmp.go
│ └── vnc.go
├── qms/
│ ├── disk.go
│ ├── power.go
│ ├── qms.go
│ ├── usb.go
│ ├── utils.go
│ └── vnc.go
├── redirect/
│ ├── acme.go
│ ├── crypto/
│ │ └── crypto.go
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ └── utils.go
├── relations/
│ ├── definitions/
│ │ ├── block.go
│ │ ├── certificate.go
│ │ ├── datacenter.go
│ │ ├── definitions.go
│ │ ├── firewall.go
│ │ ├── instance.go
│ │ ├── node.go
│ │ ├── organization.go
│ │ ├── pod.go
│ │ ├── policy.go
│ │ ├── secret.go
│ │ ├── shape.go
│ │ ├── vpc.go
│ │ └── zone.go
│ ├── registry.go
│ ├── relations.go
│ ├── response.go
│ └── utils.go
├── render/
│ ├── constants.go
│ └── render.go
├── requires/
│ ├── errors.go
│ └── requires.go
├── rokey/
│ ├── cache.go
│ ├── rokey.go
│ └── utils.go
├── router/
│ ├── certificates.go
│ ├── constants.go
│ └── router.go
├── scheduler/
│ ├── constants.go
│ ├── scheduler.go
│ ├── unit.go
│ └── utils.go
├── secondary/
│ ├── constants.go
│ ├── duo.go
│ ├── errors.go
│ ├── okta.go
│ ├── onelogin.go
│ ├── secondary.go
│ └── utils.go
├── secret/
│ ├── constants.go
│ ├── oracle.go
│ ├── secret.go
│ └── utils.go
├── session/
│ ├── constants.go
│ ├── session.go
│ └── utils.go
├── settings/
│ ├── acme.go
│ ├── auth.go
│ ├── hypervisor.go
│ ├── local.go
│ ├── registry.go
│ ├── router.go
│ ├── settings.go
│ ├── system.go
│ └── telemetry.go
├── setup/
│ └── iptables.go
├── shape/
│ ├── constants.go
│ ├── node.go
│ ├── shape.go
│ └── utils.go
├── signature/
│ ├── signature.go
│ └── utils.go
├── spec/
│ ├── constants.go
│ ├── domain.go
│ ├── firewall.go
│ ├── instance.go
│ ├── journal.go
│ ├── node.go
│ ├── spec.go
│ └── utils.go
├── state/
│ ├── arps.go
│ ├── authorities.go
│ ├── authorities_preload.go
│ ├── datacenter.go
│ ├── deployments.go
│ ├── disks.go
│ ├── domains.go
│ ├── firewalls.go
│ ├── firewalls_preload.go
│ ├── instances.go
│ ├── instances_preload.go
│ ├── network.go
│ ├── package.go
│ ├── pools.go
│ ├── runtimes.go
│ ├── schedulers.go
│ ├── state.go
│ ├── state_old.go
│ ├── virtuals.go
│ ├── vpcs.go
│ ├── zone.go
│ └── zones.go
├── static/
│ ├── file.go
│ └── static.go
├── storage/
│ ├── constants.go
│ ├── storage.go
│ └── utils.go
├── store/
│ ├── address.go
│ ├── arp.go
│ ├── disks.go
│ ├── routes.go
│ ├── usb.go
│ └── virt.go
├── subscription/
│ └── subscription.go
├── sync/
│ ├── auth.go
│ ├── nodes.go
│ ├── sync.go
│ └── vm.go
├── systemd/
│ ├── systemd.go
│ └── utils.go
├── task/
│ ├── acme.go
│ ├── advisory.go
│ ├── backing.go
│ ├── balancer.go
│ ├── blocks.go
│ ├── cache.go
│ ├── constants.go
│ ├── deployments.go
│ ├── domains.go
│ ├── imds.go
│ ├── job.go
│ ├── notification.go
│ ├── scheduler.go
│ ├── spec.go
│ ├── specindex.go
│ ├── storage.go
│ └── task.go
├── telemetry/
│ ├── constants.go
│ ├── telemetry.go
│ ├── updates.go
│ └── utils.go
├── tools/
│ ├── autoindex.py
│ ├── build_run.sh
│ ├── builder.py
│ ├── generate_demo_data.py
│ ├── generate_files.py
│ ├── package/
│ │ ├── PKGBUILD
│ │ └── README.md
│ ├── pritunl-cloud-redirect.service
│ ├── pritunl-cloud-redirect.socket
│ ├── pritunl-cloud.service
│ ├── tsc_run.sh
│ ├── virt-install/
│ │ ├── README.md
│ │ ├── download.sh
│ │ ├── install/
│ │ │ ├── almalinux10.sh
│ │ │ ├── almalinux8.sh
│ │ │ ├── almalinux9.sh
│ │ │ ├── alpinelinux.sh
│ │ │ ├── archlinux.sh
│ │ │ ├── fedora43.sh
│ │ │ ├── fedora44.sh
│ │ │ ├── freebsd.sh
│ │ │ ├── oraclelinux10.sh
│ │ │ ├── oraclelinux7.sh
│ │ │ ├── oraclelinux8.sh
│ │ │ ├── oraclelinux9.sh
│ │ │ ├── rockylinux10.sh
│ │ │ ├── rockylinux8.sh
│ │ │ ├── rockylinux9.sh
│ │ │ ├── ubuntu24.sh
│ │ │ └── ubuntu26.sh
│ │ └── setup/
│ │ ├── alpine.sh
│ │ ├── arch.sh
│ │ ├── debian.sh
│ │ ├── fedora.sh
│ │ ├── freebsd.sh
│ │ ├── rhel10.sh
│ │ ├── rhel7.sh
│ │ ├── rhel8.sh
│ │ └── rhel9.sh
│ └── webpack_run.sh
├── tpm/
│ ├── tpm.go
│ └── utils.go
├── twilio/
│ ├── twilio.go
│ └── utils.go
├── uhandlers/
│ ├── alert.go
│ ├── auth.go
│ ├── authority.go
│ ├── balancer.go
│ ├── certificate.go
│ ├── check.go
│ ├── completion.go
│ ├── csrf.go
│ ├── datacenter.go
│ ├── devices.go
│ ├── disk.go
│ ├── domain.go
│ ├── event.go
│ ├── firewall.go
│ ├── handlers.go
│ ├── image.go
│ ├── instance.go
│ ├── license.go
│ ├── node.go
│ ├── organization.go
│ ├── plan.go
│ ├── pod.go
│ ├── pool.go
│ ├── relations.go
│ ├── secret.go
│ ├── shape.go
│ ├── static.go
│ ├── theme.go
│ ├── utils.go
│ ├── vpc.go
│ └── zone.go
├── unit/
│ ├── unit.go
│ └── utils.go
├── upgrade/
│ ├── created.go
│ ├── instance.go
│ ├── journal.go
│ ├── node.go
│ ├── objectid.go
│ ├── roles.go
│ ├── state.go
│ ├── upgrade.go
│ └── zone_datacenter.go
├── usb/
│ ├── usb.go
│ └── utils.go
├── user/
│ ├── constants.go
│ ├── user.go
│ └── utils.go
├── useragent/
│ └── useragent.go
├── utils/
│ ├── crypto.go
│ ├── dns.go
│ ├── files.go
│ ├── filter.go
│ ├── limiter.go
│ ├── math.go
│ ├── misc.go
│ ├── multilock.go
│ ├── multitimeoutlock.go
│ ├── network.go
│ ├── proc.go
│ ├── prompt.go
│ ├── psutil_freebsd.go
│ ├── psutil_linux.go
│ ├── randomname.go
│ ├── request.go
│ ├── sort.go
│ ├── timeoutlock.go
│ ├── unix.go
│ └── webauthn.go
├── validator/
│ └── validator.go
├── version/
│ ├── cache.go
│ ├── utils.go
│ └── version.go
├── virtiofs/
│ ├── systemd.go
│ ├── utils.go
│ └── virtiofs.go
├── vm/
│ ├── constants.go
│ ├── sort.go
│ ├── utils.go
│ └── vm.go
├── vmdk/
│ └── utils.go
├── vpc/
│ ├── constants.go
│ ├── ip.go
│ ├── subnet.go
│ ├── utils.go
│ └── vpc.go
├── vxlan/
│ └── vxlan.go
├── www/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── Alert.ts
│ │ ├── App.tsx
│ │ ├── Constants.ts
│ │ ├── Csrf.ts
│ │ ├── EditorThemes.ts
│ │ ├── Event.ts
│ │ ├── EventEmitter.ts
│ │ ├── License.ts
│ │ ├── Loader.ts
│ │ ├── References.d.ts
│ │ ├── Router.ts
│ │ ├── Styles.tsx
│ │ ├── Theme.ts
│ │ ├── actions/
│ │ │ ├── AlertActions.ts
│ │ │ ├── AuditActions.ts
│ │ │ ├── AuthorityActions.ts
│ │ │ ├── BalancerActions.ts
│ │ │ ├── BlockActions.ts
│ │ │ ├── CertificateActions.ts
│ │ │ ├── CompletionActions.ts
│ │ │ ├── DatacenterActions.ts
│ │ │ ├── DeviceActions.ts
│ │ │ ├── DiskActions.ts
│ │ │ ├── DomainActions.ts
│ │ │ ├── FirewallActions.ts
│ │ │ ├── ImageActions.ts
│ │ │ ├── InstanceActions.ts
│ │ │ ├── LogActions.ts
│ │ │ ├── NodeActions.ts
│ │ │ ├── OrganizationActions.ts
│ │ │ ├── PlanActions.ts
│ │ │ ├── PodActions.ts
│ │ │ ├── PolicyActions.ts
│ │ │ ├── PoolActions.ts
│ │ │ ├── RelationsActions.ts
│ │ │ ├── SecretActions.ts
│ │ │ ├── SessionActions.ts
│ │ │ ├── SettingsActions.ts
│ │ │ ├── ShapeActions.ts
│ │ │ ├── StorageActions.ts
│ │ │ ├── SubscriptionActions.ts
│ │ │ ├── UserActions.ts
│ │ │ ├── VpcActions.ts
│ │ │ └── ZoneActions.ts
│ │ ├── completion/
│ │ │ ├── Cache.ts
│ │ │ ├── Engine.ts
│ │ │ └── Types.ts
│ │ ├── components/
│ │ │ ├── AdvisoryDialog.tsx
│ │ │ ├── Alert.tsx
│ │ │ ├── AlertDetailed.tsx
│ │ │ ├── AlertNew.tsx
│ │ │ ├── Alerts.tsx
│ │ │ ├── AlertsFilter.tsx
│ │ │ ├── AlertsPage.tsx
│ │ │ ├── Audit.tsx
│ │ │ ├── Audits.tsx
│ │ │ ├── AuditsPage.tsx
│ │ │ ├── Authorities.tsx
│ │ │ ├── AuthoritiesFilter.tsx
│ │ │ ├── AuthoritiesPage.tsx
│ │ │ ├── Authority.tsx
│ │ │ ├── AuthorityDetailed.tsx
│ │ │ ├── AuthorityNew.tsx
│ │ │ ├── Balancer.tsx
│ │ │ ├── BalancerBackend.tsx
│ │ │ ├── BalancerDetailed.tsx
│ │ │ ├── BalancerDomain.tsx
│ │ │ ├── BalancerNew.tsx
│ │ │ ├── Balancers.tsx
│ │ │ ├── BalancersFilter.tsx
│ │ │ ├── BalancersPage.tsx
│ │ │ ├── Block.tsx
│ │ │ ├── BlockDetailed.tsx
│ │ │ ├── BlockNew.tsx
│ │ │ ├── Blocks.tsx
│ │ │ ├── BlocksFilter.tsx
│ │ │ ├── BlocksPage.tsx
│ │ │ ├── Certificate.tsx
│ │ │ ├── CertificateDetailed.tsx
│ │ │ ├── CertificateDomain.tsx
│ │ │ ├── CertificateNew.tsx
│ │ │ ├── Certificates.tsx
│ │ │ ├── CertificatesFilter.tsx
│ │ │ ├── CertificatesPage.tsx
│ │ │ ├── ConfirmButton.tsx
│ │ │ ├── CopyButton.tsx
│ │ │ ├── Datacenter.tsx
│ │ │ ├── DatacenterDetailed.tsx
│ │ │ ├── DatacenterNew.tsx
│ │ │ ├── Datacenters.tsx
│ │ │ ├── DatacentersFilter.tsx
│ │ │ ├── DatacentersPage.tsx
│ │ │ ├── Device.tsx
│ │ │ ├── Devices.tsx
│ │ │ ├── Disk.tsx
│ │ │ ├── DiskDetailed.tsx
│ │ │ ├── DiskNew.tsx
│ │ │ ├── Disks.tsx
│ │ │ ├── DisksFilter.tsx
│ │ │ ├── DisksPage.tsx
│ │ │ ├── Domain.tsx
│ │ │ ├── DomainDetailed.tsx
│ │ │ ├── DomainNew.tsx
│ │ │ ├── DomainRecord.tsx
│ │ │ ├── Domains.tsx
│ │ │ ├── DomainsFilter.tsx
│ │ │ ├── DomainsPage.tsx
│ │ │ ├── Editor.tsx
│ │ │ ├── Firewall.tsx
│ │ │ ├── FirewallDetailed.tsx
│ │ │ ├── FirewallNew.tsx
│ │ │ ├── FirewallRule.tsx
│ │ │ ├── Firewalls.tsx
│ │ │ ├── FirewallsFilter.tsx
│ │ │ ├── FirewallsPage.tsx
│ │ │ ├── Help.tsx
│ │ │ ├── Image.tsx
│ │ │ ├── ImageDetailed.tsx
│ │ │ ├── Images.tsx
│ │ │ ├── ImagesFilter.tsx
│ │ │ ├── ImagesPage.tsx
│ │ │ ├── Instance.tsx
│ │ │ ├── InstanceDetailed.tsx
│ │ │ ├── InstanceImages.tsx
│ │ │ ├── InstanceIscsiDevice.tsx
│ │ │ ├── InstanceLicense.tsx
│ │ │ ├── InstanceMount.tsx
│ │ │ ├── InstanceNew.tsx
│ │ │ ├── InstanceNodePort.tsx
│ │ │ ├── Instances.tsx
│ │ │ ├── InstancesFilter.tsx
│ │ │ ├── InstancesPage.tsx
│ │ │ ├── LoadingBar.tsx
│ │ │ ├── LoadingCircle.tsx
│ │ │ ├── Log.tsx
│ │ │ ├── LogViewer.tsx
│ │ │ ├── Logs.tsx
│ │ │ ├── LogsFilter.tsx
│ │ │ ├── LogsPage.tsx
│ │ │ ├── Main.tsx
│ │ │ ├── MarkdownMemo.tsx
│ │ │ ├── Node.tsx
│ │ │ ├── NodeBlock.tsx
│ │ │ ├── NodeDeploy.tsx
│ │ │ ├── NodeDetailed.tsx
│ │ │ ├── NodeShare.tsx
│ │ │ ├── Nodes.tsx
│ │ │ ├── NodesFilter.tsx
│ │ │ ├── NodesPage.tsx
│ │ │ ├── NonState.tsx
│ │ │ ├── Organization.tsx
│ │ │ ├── OrganizationDetailed.tsx
│ │ │ ├── OrganizationNew.tsx
│ │ │ ├── OrganizationSelect.tsx
│ │ │ ├── Organizations.tsx
│ │ │ ├── OrganizationsFilter.tsx
│ │ │ ├── OrganizationsPage.tsx
│ │ │ ├── Page.tsx
│ │ │ ├── PageButton.tsx
│ │ │ ├── PageCreate.tsx
│ │ │ ├── PageCustom.tsx
│ │ │ ├── PageDateTime.tsx
│ │ │ ├── PageHeader.tsx
│ │ │ ├── PageInfo.tsx
│ │ │ ├── PageInput.tsx
│ │ │ ├── PageInputButton.tsx
│ │ │ ├── PageInputSwitch.tsx
│ │ │ ├── PageNew.tsx
│ │ │ ├── PageNumInput.tsx
│ │ │ ├── PagePanel.tsx
│ │ │ ├── PageSave.tsx
│ │ │ ├── PageSelect.tsx
│ │ │ ├── PageSelectButton.tsx
│ │ │ ├── PageSelectButtonConfirm.tsx
│ │ │ ├── PageSelector.tsx
│ │ │ ├── PageSplit.tsx
│ │ │ ├── PageSwitch.tsx
│ │ │ ├── PageTextArea.tsx
│ │ │ ├── Plan.tsx
│ │ │ ├── PlanDetailed.tsx
│ │ │ ├── PlanEditor.tsx
│ │ │ ├── PlanNew.tsx
│ │ │ ├── PlanStatement.tsx
│ │ │ ├── Plans.tsx
│ │ │ ├── PlansFilter.tsx
│ │ │ ├── PlansPage.tsx
│ │ │ ├── Pod.tsx
│ │ │ ├── PodDeploy.tsx
│ │ │ ├── PodDeployment.tsx
│ │ │ ├── PodDeploymentEdit.tsx
│ │ │ ├── PodDetailed.tsx
│ │ │ ├── PodEditor.tsx
│ │ │ ├── PodMigrate.tsx
│ │ │ ├── PodNew.tsx
│ │ │ ├── PodUnit.tsx
│ │ │ ├── PodWorkspace.tsx
│ │ │ ├── Pods.tsx
│ │ │ ├── PodsFilter.tsx
│ │ │ ├── PodsPage.tsx
│ │ │ ├── Policies.tsx
│ │ │ ├── PoliciesFilter.tsx
│ │ │ ├── PoliciesPage.tsx
│ │ │ ├── Policy.tsx
│ │ │ ├── PolicyDetailed.tsx
│ │ │ ├── PolicyNew.tsx
│ │ │ ├── PolicyRule.tsx
│ │ │ ├── Pool.tsx
│ │ │ ├── PoolDetailed.tsx
│ │ │ ├── PoolNew.tsx
│ │ │ ├── Pools.tsx
│ │ │ ├── PoolsFilter.tsx
│ │ │ ├── PoolsPage.tsx
│ │ │ ├── Relations.tsx
│ │ │ ├── RouterLink.tsx
│ │ │ ├── RouterRedirect.tsx
│ │ │ ├── RouterRoute.tsx
│ │ │ ├── RouterRoutes.tsx
│ │ │ ├── SearchInput.tsx
│ │ │ ├── Secret.tsx
│ │ │ ├── SecretDetailed.tsx
│ │ │ ├── SecretNew.tsx
│ │ │ ├── Secrets.tsx
│ │ │ ├── SecretsFilter.tsx
│ │ │ ├── SecretsPage.tsx
│ │ │ ├── Session.tsx
│ │ │ ├── Sessions.tsx
│ │ │ ├── Settings.tsx
│ │ │ ├── SettingsProvider.tsx
│ │ │ ├── SettingsSecondaryProvider.tsx
│ │ │ ├── Shape.tsx
│ │ │ ├── ShapeDetailed.tsx
│ │ │ ├── ShapeNew.tsx
│ │ │ ├── Shapes.tsx
│ │ │ ├── ShapesFilter.tsx
│ │ │ ├── ShapesPage.tsx
│ │ │ ├── Storage.tsx
│ │ │ ├── StorageDetailed.tsx
│ │ │ ├── StorageNew.tsx
│ │ │ ├── Storages.tsx
│ │ │ ├── StoragesFilter.tsx
│ │ │ ├── StoragesPage.tsx
│ │ │ ├── Subscription.tsx
│ │ │ ├── Switch.tsx
│ │ │ ├── SwitchNull.tsx
│ │ │ ├── User.tsx
│ │ │ ├── UserDetailed.tsx
│ │ │ ├── Users.tsx
│ │ │ ├── UsersFilter.tsx
│ │ │ ├── UsersPage.tsx
│ │ │ ├── Vpc.tsx
│ │ │ ├── VpcArp.tsx
│ │ │ ├── VpcDetailed.tsx
│ │ │ ├── VpcLinkUri.tsx
│ │ │ ├── VpcMap.tsx
│ │ │ ├── VpcNew.tsx
│ │ │ ├── VpcRoute.tsx
│ │ │ ├── VpcSubnet.tsx
│ │ │ ├── Vpcs.tsx
│ │ │ ├── VpcsFilter.tsx
│ │ │ ├── VpcsPage.tsx
│ │ │ ├── Zone.tsx
│ │ │ ├── ZoneDetailed.tsx
│ │ │ ├── ZoneNew.tsx
│ │ │ ├── Zones.tsx
│ │ │ ├── ZonesFilter.tsx
│ │ │ └── ZonesPage.tsx
│ │ ├── dispatcher/
│ │ │ ├── Base.ts
│ │ │ ├── Dispatcher.ts
│ │ │ ├── EventDispatcher.ts
│ │ │ └── LoadingDispatcher.ts
│ │ ├── stores/
│ │ │ ├── AlertsStore.ts
│ │ │ ├── AuditsStore.ts
│ │ │ ├── AuthoritiesStore.ts
│ │ │ ├── BalancersStore.ts
│ │ │ ├── BlocksStore.ts
│ │ │ ├── CertificatesStore.ts
│ │ │ ├── CompletionStore.ts
│ │ │ ├── DatacentersStore.ts
│ │ │ ├── DevicesStore.ts
│ │ │ ├── DisksStore.ts
│ │ │ ├── DomainsNameStore.ts
│ │ │ ├── DomainsStore.ts
│ │ │ ├── FirewallsStore.ts
│ │ │ ├── ImagesDatacenterStore.ts
│ │ │ ├── ImagesStore.ts
│ │ │ ├── InstancesNodeStore.ts
│ │ │ ├── InstancesStore.ts
│ │ │ ├── LoadingStore.ts
│ │ │ ├── LogsStore.ts
│ │ │ ├── NodesStore.ts
│ │ │ ├── NodesZoneStore.ts
│ │ │ ├── OrganizationsStore.ts
│ │ │ ├── PlansStore.ts
│ │ │ ├── PodsStore.ts
│ │ │ ├── PodsUnitStore.ts
│ │ │ ├── PoliciesStore.ts
│ │ │ ├── PoolsStore.ts
│ │ │ ├── SecretsStore.ts
│ │ │ ├── SessionsStore.ts
│ │ │ ├── SettingsStore.ts
│ │ │ ├── ShapesStore.ts
│ │ │ ├── StoragesStore.ts
│ │ │ ├── SubscriptionStore.ts
│ │ │ ├── UserStore.ts
│ │ │ ├── UsersStore.ts
│ │ │ ├── VpcsNameStore.ts
│ │ │ ├── VpcsStore.ts
│ │ │ └── ZonesStore.ts
│ │ ├── types/
│ │ │ ├── AgentTypes.ts
│ │ │ ├── AlertTypes.ts
│ │ │ ├── AuditTypes.ts
│ │ │ ├── AuthorityTypes.ts
│ │ │ ├── BalancerTypes.ts
│ │ │ ├── BlockTypes.ts
│ │ │ ├── CertificateTypes.ts
│ │ │ ├── CompletionTypes.ts
│ │ │ ├── DatacenterTypes.ts
│ │ │ ├── DeviceTypes.ts
│ │ │ ├── DiskTypes.ts
│ │ │ ├── DomainTypes.ts
│ │ │ ├── FirewallTypes.ts
│ │ │ ├── GlobalTypes.ts
│ │ │ ├── ImageTypes.ts
│ │ │ ├── InstanceTypes.ts
│ │ │ ├── LoadingTypes.ts
│ │ │ ├── LogTypes.ts
│ │ │ ├── NodeTypes.ts
│ │ │ ├── OrganizationTypes.ts
│ │ │ ├── PlanTypes.ts
│ │ │ ├── PodTypes.ts
│ │ │ ├── PolicyTypes.ts
│ │ │ ├── PoolTypes.ts
│ │ │ ├── RelationTypes.ts
│ │ │ ├── RouterTypes.ts
│ │ │ ├── SecretTypes.ts
│ │ │ ├── SessionTypes.ts
│ │ │ ├── SettingsTypes.ts
│ │ │ ├── ShapeTypes.ts
│ │ │ ├── StorageTypes.ts
│ │ │ ├── SubscriptionTypes.ts
│ │ │ ├── UserTypes.ts
│ │ │ ├── VpcTypes.ts
│ │ │ └── ZoneTypes.ts
│ │ └── utils/
│ │ ├── AgentUtils.ts
│ │ └── MiscUtils.tsx
│ ├── build.sh
│ ├── build_remote.sh
│ ├── dist/
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── static/
│ │ │ ├── blueprint-datetime2.css
│ │ │ ├── blueprint-icons.css
│ │ │ ├── blueprint3.css
│ │ │ ├── blueprint5.css
│ │ │ ├── global.css
│ │ │ └── normalize.css
│ │ └── uindex.html
│ ├── dist-dev/
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── static/
│ │ │ ├── blueprint-datetime2.css
│ │ │ ├── blueprint-icons.css
│ │ │ ├── blueprint3.css
│ │ │ ├── blueprint5.css
│ │ │ ├── global.css
│ │ │ └── normalize.css
│ │ └── uindex.html
│ ├── index.html
│ ├── index_dist.html
│ ├── login.html
│ ├── package.json
│ ├── styles/
│ │ ├── blueprint.css
│ │ └── global.css
│ ├── tsconfig.json
│ ├── uindex.html
│ ├── uindex_dist.html
│ ├── webpack.config.js
│ └── webpack.dev.config.js
└── zone/
├── constants.go
├── utils.go
└── zone.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
www/app/EditorThemes.ts linguist-vendored
*.html linguist-vendored
*.css linguist-vendored
*.js linguist-vendored
================================================
FILE: .gitignore
================================================
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
*.pyc
*.egg
*.egg-info
build_keys.json
/pritunl-cloud
/builder/builder
/agent/agent
/imds/server/server
================================================
FILE: CHANGES
================================================
pritunl-cloud changelog
=======================
<%= version %>
Add Google Cloud DNS support
Add support to manual renew certificates
Fix host network bridge management issues
Optimize database indexes
Version 2.0.3665.99 2025-12-06
------------------------------
Add internal DNS system
Add arch linux support
Improve Route53 DNS management
Improve instance layout in web console
Improve instance web console VNC
Version 2.0.3616.97 2025-10-18
------------------------------
Add journal kind to pods
Add support for QEMU 10
Improve QEMU tuning
Fix relations query
Fix RHEL 7 IPv6 network configuration
Add imds service recovery
Add update advisories
Web console layout improvements
Version 2.0.3592.49 2025-09-24
------------------------------
Add pod system
Add imds service
Add secrets storage
Add LVM storage pools
Add DNS TXT verification for Lets Encrypt
Add support for custom vpc arp entries
Add node port support
Add dhcp client and server
Add cloud script support
Version 1.2.2933.86 2023-12-05
------------------------------
Fix fast login issues
Version 1.2.2900.76 2023-11-02
------------------------------
Improve single sign-on fast login
Version 1.2.2853.96 2023-09-16
------------------------------
Add VPC network maps
Fix QEMU desktop GUI on Fedora 38
Version 1.2.2759.95 2023-06-14
------------------------------
Add support for Fedora 38
Add fast login
Version 1.2.2653.26 2023-02-28
------------------------------
Improve instance backup support
Version 1.2.2626.74 2023-02-01
------------------------------
Fix kernel compatibility issue
Version 1.2.2626.25 2023-02-01
------------------------------
Support RHEL 9
Web interface design changes
Fix network configuration issue with IPv6 instances
Version 1.2.2415.36 2022-07-05
------------------------------
Update cloud init configuration
Version 1.2.2415.30 2022-07-05
------------------------------
Update QEMU configuration
Version 1.2.2414.59 2022-07-04
------------------------------
Add FreeBSD support
Add Windows 11 support
Add instance TPM support
Add instance DHCP server
Configure node firewall in node init
Version 1.2.2400.46 2022-06-20
------------------------------
Fix QEMU feature detection
Version 1.2.2400.30 2022-06-20
------------------------------
Add AlmaLinux image labels
Version 1.2.2399.48 2022-06-19
------------------------------
Show running QEMU version in instance info
Improve Lets Encrypt certificates
Version 1.2.2397.83 2022-06-17
------------------------------
Support QEMU 7.0.0
Support Azure users with more then 50 groups
Version 1.2.2336.5 2022-04-17
-----------------------------
Fix compatibility issue with Fedora update
Version 1.2.2335.81 2022-04-16
------------------------------
Add support for MongoDB unix socket
Version 1.2.2334.82 2022-04-15
------------------------------
Support IPv6 only instances
Version 1.2.2334.69 2022-04-15
------------------------------
Fix issue with instance startup
Version 1.2.2333.97 2022-04-14
------------------------------
Improve instance management
Version 1.2.2333.91 2022-04-14
------------------------------
Improve instance IPv6 networking
Version 1.2.2333.80 2022-04-14
------------------------------
Improve instance networking
Version 1.2.2330.66 2022-04-11
------------------------------
Add option to disable public IPv6 address
Version 1.2.2330.2 2022-04-11
-----------------------------
Improve node init support
Improve instance isolation
Version 1.2.2324.79 2022-04-05
------------------------------
Improve IPv6 networking
Version 1.2.2324.56 2022-04-05
------------------------------
Improve node init support
Add mtu check command
Fix static IPv6 issues
Version 1.2.2301.94 2022-03-13
------------------------------
Add support for internal only jumbo frames
Update image labels for Ubuntu
Version 1.2.2289.56 2022-03-01
------------------------------
Improve node init support
Version 1.2.2287.69 2022-02-27
------------------------------
Improve host networking
Version 1.2.2286.62 2022-02-26
------------------------------
Fix issues with static IPv6 configuration
Version 1.2.2262.39 2022-02-02
------------------------------
Fix U2F migration to WebAuthn issues
Version 1.2.2261.49 2022-02-01
------------------------------
Web interface improvements
Version 1.2.2261.45 2022-02-01
------------------------------
Improve Oracle Cloud networking
Version 1.2.2260.40 2022-01-31
------------------------------
Add hugepages support
Add support for Azure graph API
Add instance gui
Add instance spice server
Add instance source destination check
Add JumpCloud single sign-on
Add instance root password option
Improve instance sandboxing
Version 1.2.2184.82 2021-11-16
------------------------------
Add Oracle Cloud vnic support
Improve qemu support
Version 1.2.2144.31 2021-10-07
------------------------------
Web interface improvements
Version 1.2.2141.15 2021-10-04
------------------------------
Fix zone defaults
Version 1.2.2140.92 2021-10-03
------------------------------
Support instance networking without bridge
Version 1.2.2091.92 2021-08-15
------------------------------
Improve instance networking
Version 1.2.2011.58 2021-05-27
------------------------------
Add uefi instance support
Add secure boot instance support
Add pci passthrough
Add disk resizing
Add disk passthrough
Add iscsi instance disk support
Add instance iso support
Support add and remove USB devices on running instance
Support add and remove disks on running instance
Support wildcard certificates
Format username capitalization on update
Move instance runtime files to run directory
Web interface improvements
Version 1.2.1807.79 2020-11-04
------------------------------
Improve online disk backup
Add VNC client to web console
Add local backup command
Web interface improvements
Version 1.2.1772.58 2020-09-30
------------------------------
Fix issue with multiple instance disks
Fix startup issue
Version 1.0.1743.55 2020-09-01
------------------------------
Web server improvements
Version 1.0.1623.75 2020-05-04
------------------------------
Add web socket support to load balancers
Version 1.2.1595.50 2020-04-06
------------------------------
Add support for network alias interfaces
Version 1.2.1594.77 2020-04-05
------------------------------
Improve node management
Version 1.2.1594.70 2020-04-05
------------------------------
Networking improvements
Version 1.2.1589.78 2020-03-31
------------------------------
Add VPC subnets
Move default data directory
Support IPv6 static blocks
Interface improvements
Add load balancers
Version 1.0.1452.55 2019-11-15
------------------------------
Improve acme v2 support
Version 1.0.1448.49 2019-11-11
------------------------------
Support acme v2
Instance networking improvements
Web interface improvements
Version 1.0.1413.18 2019-10-07
------------------------------
Add support for USB passthrough
Version 1.0.1338.74 2019-07-24
------------------------------
Improve instance management
Version 1.0.1337.5 2019-07-23
-----------------------------
Improve instance management
Add uptime to instance info
Generate random default password
Version 1.0.1213.83 2019-03-21
------------------------------
Web interface improvements
Version 1.0.1213.82 2019-03-21
------------------------------
Add option to disable instance public and host address
Version 1.0.1206.81 2019-03-14
------------------------------
Add VGA option to node settings
Version 1.0.1200.31 2019-03-08
------------------------------
Improve network performance
Version 1.0.1200.25 2019-03-08
------------------------------
Improve instance management
Version 1.0.1199.30 2019-03-07
------------------------------
Fix instance creation issue
Version 1.0.1199.28 2019-03-07
------------------------------
Add instance vnc support
Version 1.0.1197.13 2019-03-05
------------------------------
Set instance hostname
Version 1.0.1189.79 2019-02-25
------------------------------
Improve U2F support
Web interface improvements
Version 1.0.1181.24 2019-02-17
------------------------------
Add redirect server option to node settings
Version 1.0.1180.14 2019-02-16
------------------------------
Add support for Oracle Cloud
Version 1.0.1179.24 2019-02-15
------------------------------
Add host networking
Version 1.0.1173.24 2019-02-09
------------------------------
Add VXLan support
Version 1.0.1169.1 2019-02-05
-----------------------------
Fix node configuration
Version 1.0.1168.95 2019-02-04
------------------------------
Improve node management
Version 1.0.1168.94 2019-02-04
------------------------------
Improve node management
Version 1.0.1168.33 2019-02-04
------------------------------
Add support for static instance IP addresses
Improve instance management
Version 1.0.1155.32 2019-01-22
------------------------------
Add support for Oracle Cloud archive storage
Version 1.0.1154.31 2019-01-21
------------------------------
Improve instance startup
Version 1.0.1154.28 2019-01-21
------------------------------
Improve instance management
Version 1.0.1153.36 2019-01-20
------------------------------
Improve storage management
Version 1.0.1153.8 2019-01-20
-----------------------------
Add storage class to images
Version 1.0.1151.28 2019-01-18
------------------------------
Improve instance destroy
Version 1.0.1150.31 2019-01-17
------------------------------
Add copy to clipboard to web console
Version 1.0.1149.32 2019-01-16
------------------------------
Add automatic backup scheduling
Version 1.0.1147.30 2019-01-14
------------------------------
Add disk backup and restore
Version 1.0.1144.28 2019-01-11
------------------------------
Jumbo frames support
Instance management interface improvements
Version 1.0.1142.87 2019-01-09
------------------------------
Reliability improvements
Version 1.0.1141.35 2019-01-08
------------------------------
Improve instance management
Version 1.0.1140.33 2019-01-07
------------------------------
Add instance and disk delete protection
Web interface improvements
Version 1.0.1135.30 2019-01-02
------------------------------
Node management improvements
Version 1.0.1134.7 2019-01-01
-----------------------------
Improve node scalability
Improve firewall performance
Version 1.0.1129.93 2018-12-27
------------------------------
Linked disk improvements
Version 1.0.1129.29 2018-12-27
------------------------------
Add support for multiple network interfaces
Add support for linked disk images
Version 1.0.1124.31 2018-12-22
------------------------------
Improve instances interface in web console
Version 1.0.1118.32 2018-12-16
------------------------------
Virtual machine improvements
Version 1.0.1108.99 2018-12-06
------------------------------
Fix issue with Azure single sign-on
Version 1.0.1091.33 2018-11-19
------------------------------
Initial release
================================================
FILE: LICENSE
================================================
Copyright (c) 2013-2026 Pritunl
LICENSE SUMMARY
* License does not expire
* Can be used on unlimited sites, servers
* Source-code or binary products cannot be resold or distributed
* Non-commercial use only
* Can modify source-code but cannot distribute modifications (derivative works)
PREAMBLE
This Agreement, signed on Nov 12, 2014 [hereinafter: Effective Date] governs
the relationship between you, a private person, (hereinafter: Licensee) and
Pritunl, a private person whose principal place of business is United States
(Hereinafter: Licensor). This Agreement sets the terms, rights, restrictions
and obligations on using [Pritunl] (hereinafter: The Software) created and
owned by Licensor, as detailed herein
LICENSE GRANT
Licensor hereby grants Licensee a Personal, Non-assignable &
non-transferable, Non-commercial, Royalty free, Without the rights to create
derivative works, Non-exclusive license, all with accordance with the terms
set forth and other legal restrictions set forth in 3rd party software used
while running Software.
Limited: Licensee may use Software for the purpose of:
* Running Software on Licensee's Website[s] and Server[s]
* Allowing 3rd Parties to run Software on Licensee's Website[s] and Server[s]
* Publishing Software's output to Licensee and 3rd Parties
* Modify Software to suit Licensee's needs and specifications.
Non Assignable & Non-Transferable: Licensee may not assign or transfer his
rights and duties under this license.
Non-Commercial: Licensee may not use Software for commercial purposes. for the
purpose of this license, commercial purposes means that a 3rd party has to pay
in order to access Software or that the Website that runs Software is behind a
paywall.
TERM & TERMINATION
The Term of this license shall be until terminated. Licensor may terminate
this Agreement, including Licensee's license in the case where Licensee:
* became insolvent or otherwise entered into any liquidation process; or
exported The Software to any jurisdiction where licensor may not enforce his
rights under this agreements in; or
* Licensee was in breach of any of this license's terms and conditions and
such breach was not cured, immediately upon notification; or
* Licensee in breach of any of the terms of clause 2 to this license; or
* Licensee otherwise entered into any arrangement which caused Licensor to be
unable to enforce his rights under this License.
UPGRADES, UPDATES AND FIXES
Licensor may provide Licensee, from time to time, with Upgrades, Updates or
Fixes, as detailed herein and according to his sole discretion. Licensee
hereby warrants to keep The Software up-to-date and install all relevant
updates and fixes, and may, at his sole discretion, purchase upgrades,
according to the rates set by Licensor. Licensor shall provide any update or
Fix free of charge; however, nothing in this Agreement shall require Licensor
to provide Updates or Fixes.
Upgrades: for the purpose of this license, an Upgrade shall be a material
amendment in The Software, which contains new features and or major
performance improvements and shall be marked as a new version number. For
example, should Licensee purchase The Software under version 1.X.X, an upgrade
shall commence under number 2.0.0.
Updates: for the purpose of this license, an update shall be a minor amendment
in The Software, which may contain new features or minor improvements and
shall be marked as a new sub-version number. For example, should Licensee
purchase The Software under version 1.1.X, an upgrade shall commence under
number 1.2.0.
Fix: for the purpose of this license, a fix shall be a minor amendment in The
Software, intended to remove bugs or alter minor features which impair the The
Software's functionality. A fix shall be marked as a new sub-sub-version
number. For example, should Licensee purchase Software under version 1.1.1,
an upgrade shall commence under number 1.1.2.
SUPPORT
Software is provided under an AS-IS basis and without any support, updates or
maintenance. Nothing in this Agreement shall require Licensor to provide
Licensee with support or fixes to any bug, failure, mis-performance or other
defect in The Software.
Bug Notification: Licensee may provide Licensor of details regarding any bug,
defect or failure in The Software promptly and with no delay from such event;
Licensee shall comply with Licensor's request for information regarding bugs,
defects or failures and furnish him with information, screenshots and try to
reproduce such bugs, defects or failures.
Feature Request: Licensee may request additional features in Software,
provided, however, that (i) Licensee shall waive any claim or right in such
feature should feature be developed by Licensor; (ii) Licensee shall be
prohibited from developing the feature, or disclose such feature request, or
feature, to any 3rd party directly competing with Licensor or any 3rd party
which may be, following the development of such feature, in direct competition
with Licensor; (iii) Licensee warrants that feature does not infringe any 3rd
party patent, trademark, trade-secret or any other intellectual property
right; and (iv) Licensee developed, envisioned or created the feature solely
by himself.
Contribution: Licensee may submit additional code for the Software,
provided, however, that (i) Licensee hereby irrevocably assigns all right,
title, and interest in such contribution to Licensor upon submission; (ii)
Licensee hereby grants Licensor a perpetual, worldwide, royalty-free,
irrevocable license to use, modify, sublicense, and relicense such
contribution under any license terms Licensor chooses, including without
limitation less restrictive licenses such as AGPL; and (iii) Licensee
represents and warrants that the contribution is Licensee's original work
and does not infringe upon any third-party intellectual property rights; and
(iv) Licensee also waives any moral rights in the contribution to the extent
permitted by law.
LIABILITY
To the extent permitted under Law, The Software is provided under an AS-IS
basis. Licensor shall never, and without any limit, be liable for any damage,
cost, expense or any other payment incurred by Licensee as a result of
Software's actions, failure, bugs and/or any other interaction between The
Software and Licensee's end-equipment, computers, other software or any 3rd
party, end-equipment, computer or services. Moreover, Licensor shall never be
liable for any defect in source code written by Licensee when relying on The
Software or using The Software's source code.
WARRANTY
Intellectual Property: Licensor hereby warrants that The Software does not
violate or infringe any 3rd party claims in regards to intellectual property,
patents and/or trademarks and that to the best of its knowledge no legal
action has been taken against it for any infringement or violation of any 3rd
party intellectual property rights.
No-Warranty: The Software is provided without any warranty; Licensor hereby
disclaims any warranty that The Software shall be error free, without defects
or code which may cause damage to Licensee's computers or to Licensee, and
that Software shall be functional. Licensee shall be solely liable to any
damage, defect or loss incurred as a result of operating software and
undertake the risks contained in running The Software on License's Server[s]
and Website[s].
Prior Inspection: Licensee hereby states that he inspected The Software
thoroughly and found it satisfactory and adequate to his needs, that it does
not interfere with his regular operation and that it does meet the standards
and scope of his computer systems and architecture. Licensee found that The
Software interacts with his development, website and server environment and
that it does not infringe any of End User License Agreement of any software
Licensee may use in performing his services. Licensee hereby waives any claims
regarding The Software's incompatibility, performance, results and features,
and warrants that he inspected the The Software.
INDEMNIFICATION
Licensee hereby warrants to hold Licensor harmless and indemnify Licensor for
any lawsuit brought against it in regards to Licensee's use of The Software in
means that violate, breach or otherwise circumvent this license, Licensor's
intellectual property rights or Licensor's title in The Software. Licensor
shall promptly notify Licensee in case of such legal action and request
Licensee's consent prior to any settlement in relation to such lawsuit or
claim.
GOVERNING LAW, JURISDICTION
Licensee hereby agrees not to initiate class-action lawsuits against Licensor
in relation to this license and to compensate Licensor for any legal fees,
cost or attorney fees should any claim brought by Licensee against Licensor be
denied, in part or in full.
================================================
FILE: README.md
================================================
# pritunl-cloud: declarative kvm virtualization
[](https://github.com/pritunl)
[](https://twitter.com/pritunl)
[](https://pritunl.substack.com/)
[](https://forum.pritunl.com)
[Pritunl-Cloud](https://cloud.pritunl.com) is a declarative KVM virtualization
platform with shell and python based live updating templates. Documentation
and more information can be found at
[docs.pritunl.com](https://docs.pritunl.com/kb/cloud)
[](https://docs.pritunl.com/kb/cloud)
## Install from Source
```bash
# Install Required Tools
sudo dnf -y install git-core iptables net-tools ipset ipvsadm xorriso qemu-kvm qemu-img swtpm-tools
sudo rm -rf /usr/local/go
wget https://go.dev/dl/go1.25.5.linux-amd64.tar.gz
echo "9e9b755d63b36acf30c12a9a3fc379243714c1c6d3dd72861da637f336ebb35b go1.25.5.linux-amd64.tar.gz" | sha256sum -c - && sudo tar -C /usr/local -xf go1.25.5.linux-amd64.tar.gz
rm -f go1.25.5.linux-amd64.tar.gz
tee -a ~/.bashrc << EOF
export GOPATH=\$HOME/go
export GOROOT=/usr/local/go
export PATH=/usr/local/go/bin:\$PATH
EOF
source ~/.bashrc
# Install MongoDB
sudo dnf -y install podman
git clone https://github.com/pritunl/toolbox.git
cd toolbox/mongodb-container
sudo podman build --rm -t mongo .
cd
sudo mkdir /var/lib/mongo
sudo chown 277:277 /var/lib/mongo
sudo tee /etc/containers/systemd/mongodb-podman.container << EOF
[Unit]
Description=MongoDB Podman Service
[Container]
Image=localhost/mongo
ContainerName=mongodb
Environment=DB_NAME=pritunl-cloud
Environment=CACHE_SIZE=1
User=mongodb
Volume=/var/lib/mongo:/data/db:Z
PublishPort=127.0.0.1:27017:27017
PodmanArgs=--cpus=1 --memory=2g
[Service]
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl start mongodb-podman.service
sleep 3
sudo cat /var/lib/mongo/credentials.txt
# Build Pritunl Cloud (update with latest version from releases)
go install -v github.com/pritunl/pritunl-cloud@2.0.3616.97
go install -v github.com/pritunl/pritunl-cloud/redirect@2.0.3616.97
go install -v github.com/pritunl/pritunl-cloud/agent@2.0.3616.97
GOOS=freebsd GOARCH=amd64 go install -v github.com/pritunl/pritunl-cloud/agent@2.0.3616.97
# Install Systemd Units
sudo cp $(ls -d ~/go/pkg/mod/github.com/pritunl/pritunl-cloud@v* | sort -V | tail -n 1)/tools/pritunl-cloud.service /etc/systemd/system/
sudo cp $(ls -d ~/go/pkg/mod/github.com/pritunl/pritunl-cloud@v* | sort -V | tail -n 1)/tools/pritunl-cloud-redirect.socket /etc/systemd/system/
sudo cp $(ls -d ~/go/pkg/mod/github.com/pritunl/pritunl-cloud@v* | sort -V | tail -n 1)/tools/pritunl-cloud-redirect.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo useradd -r -s /sbin/nologin -c 'Pritunl web server' pritunl-cloud-web
# Install Pritunl Cloud
sudo mkdir -p /usr/share/pritunl-cloud/www/
sudo cp -r $(ls -d ~/go/pkg/mod/github.com/pritunl/pritunl-cloud@v* | sort -V | tail -n 1)/www/dist/. /usr/share/pritunl-cloud/www/
sudo cp ~/go/bin/pritunl-cloud /usr/bin/pritunl-cloud
sudo cp ~/go/bin/redirect /usr/bin/pritunl-cloud-redirect
sudo cp ~/go/bin/agent /usr/bin/pritunl-cloud-agent
sudo cp ~/go/bin/freebsd_amd64/agent /usr/bin/pritunl-cloud-agent-bsd
sudo systemctl enable --now pritunl-cloud
```
## License
Please refer to the [`LICENSE`](LICENSE) file for a copy of the license.
================================================
FILE: acme/acme.go
================================================
package acme
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"strings"
"time"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/certificate"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/dns"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/secret"
"github.com/pritunl/pritunl-cloud/settings"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/acme"
)
func Generate(db *database.Database, cert *certificate.Certificate) (
err error) {
acmeType := cert.AcmeType
if acmeType == "" {
acmeType = certificate.AcmeHTTP
}
acmeAuth := cert.AcmeAuth
logrus.WithFields(logrus.Fields{
"certificate": cert.Name,
"domains": cert.AcmeDomains,
"acme_type": acmeType,
"acme_auth": acmeAuth,
}).Info("acme: Generating acme certificate")
if cert.AcmeDomains == nil || len(cert.AcmeDomains) == 0 {
err = &errortypes.UnknownError{
errors.Wrap(err, "acme: No acme domains"),
}
return
}
var dnsSvc dns.Service
if acmeType == certificate.AcmeDNS {
var secr *secret.Secret
if cert.Organization.IsZero() {
secr, err = secret.Get(db, cert.AcmeSecret)
if err != nil {
return
}
} else {
secr, err = secret.GetOrg(db, cert.Organization, cert.AcmeSecret)
if err != nil {
return
}
}
if secr == nil {
err = &errortypes.UnknownError{
errors.Wrap(err, "acme: ACME secret not found"),
}
return
}
if acmeAuth == certificate.AcmeAWS {
dnsSvc = &dns.Aws{}
} else if acmeAuth == certificate.AcmeCloudflare {
dnsSvc = &dns.Cloudflare{}
} else if acmeAuth == certificate.AcmeOracleCloud {
dnsSvc = &dns.Oracle{}
} else if acmeAuth == certificate.AcmeGoogleCloud {
dnsSvc = &dns.Google{}
} else {
err = &errortypes.UnknownError{
errors.Wrapf(err,
"acme: Unknown acme auth type %s", acmeAuth),
}
return
}
err = dnsSvc.Connect(db, secr)
if err != nil {
return
}
}
var acctKey *rsa.PrivateKey
if cert.AcmeAccount != "" {
acctBlock, _ := pem.Decode([]byte(cert.AcmeAccount))
if acctBlock == nil {
err = &errortypes.ParseError{
errors.New("acme: Failed to decode account key"),
}
return
}
acctKey, err = x509.ParsePKCS1PrivateKey(acctBlock.Bytes)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "acme: Failed to parse account key"),
}
return
}
} else {
acctKey, err = rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "acme: Failed to generate account key"),
}
return
}
acctBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(acctKey),
}
cert.AcmeAccount = string(pem.EncodeToMemory(acctBlock))
err = cert.CommitFields(db, set.NewSet("acme_account"))
if err != nil {
return
}
}
acct := &acme.Account{}
client := &acme.Client{
DirectoryURL: AcmeDirectory,
Key: acctKey,
}
_, err = client.Register(context.Background(), acct, acme.AcceptTOS)
if err != nil {
if err == acme.ErrAccountAlreadyExists {
err = nil
} else {
err = &errortypes.RequestError{
errors.Wrap(err, "acme: Failed to register account"),
}
return
}
}
order, err := client.AuthorizeOrder(
context.Background(), acme.DomainIDs(cert.AcmeDomains...))
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "acme: Failed to authorize order"),
}
return
}
if order.Status == acme.StatusReady {
err = create(db, cert, client, order)
if err != nil {
return
}
return
} else if order.Status != acme.StatusPending {
err = &errortypes.RequestError{
errors.Newf(
"acme: Authorize order status '%s' not pending",
order.Status,
),
}
return
}
authzUrls := order.AuthzURLs
for _, authzUrl := range authzUrls {
authz, e := client.GetAuthorization(
context.Background(), authzUrl)
if e != nil {
err = &errortypes.RequestError{
errors.Wrap(e, "acme: Failed to get authorization"),
}
return
}
if authz.Status != acme.StatusPending {
continue
}
var authzChal *acme.Challenge
for _, c := range authz.Challenges {
if acmeType == certificate.AcmeDNS {
if c.Type == "dns-01" {
authzChal = c
break
}
} else {
if c.Type == "http-01" {
authzChal = c
break
}
}
}
if authzChal == nil {
revoke(client, authzUrls)
err = &errortypes.RequestError{
errors.New(
"acme: Authorization challenge not available"),
}
return
}
var chal *Challenge
var chalToken string
var chalDomain string
if acmeType == certificate.AcmeDNS {
chalToken, err = client.DNS01ChallengeRecord(authzChal.Token)
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "acme: Challenge record error"),
}
return
}
chalDomain = fmt.Sprintf(
"_acme-challenge.%s.", authz.Identifier.Value)
ops := []*dns.Operation{
&dns.Operation{
Operation: dns.UPSERT,
Value: "\"" + chalToken + "\"",
},
}
err = dnsSvc.DnsCommit(db, chalDomain, "TXT", ops)
if err != nil {
return
}
defer func() {
delOps := []*dns.Operation{
&dns.Operation{
Operation: dns.DELETE,
Value: "\"" + chalToken + "\"",
},
}
e := dnsSvc.DnsCommit(db, chalDomain, "TXT", delOps)
if e != nil {
logrus.WithFields(logrus.Fields{
"certificate": cert.Name,
"domain": chalDomain,
"acme_type": acmeType,
"acme_auth": acmeAuth,
"error": e,
}).Error("acme: Failed to remove DNS TXT record")
}
}()
matched, e := DnsTxtWait(chalDomain, chalToken)
if e != nil {
err = e
return
}
if !matched {
logrus.WithFields(logrus.Fields{
"certificate": cert.Name,
"domain": chalDomain,
"acme_type": acmeType,
"acme_auth": acmeAuth,
}).Warning("acme: Local DNS TXT test lookup failed")
}
time.Sleep(time.Duration(settings.Acme.DnsDelay) * time.Second)
} else {
resp, e := client.HTTP01ChallengeResponse(authzChal.Token)
if e != nil {
revoke(client, authzUrls)
err = &errortypes.RequestError{
errors.Wrap(e, "acme: Challenge response failed"),
}
return
}
chal = &Challenge{
Id: authzChal.Token,
Resource: resp,
Timestamp: time.Now(),
}
err = chal.Insert(db)
if err != nil {
return
}
chalMsg := &ChallengeMsg{
Token: authzChal.Token,
Response: resp,
}
err = chalMsg.Publish(db)
if err != nil {
return
}
time.Sleep(300 * time.Millisecond)
}
_, err = client.Accept(context.Background(), authzChal)
if err != nil {
revoke(client, authzUrls)
err = &errortypes.RequestError{
errors.Wrap(err, "acme: Authorization accept failed"),
}
return
}
_, err = client.WaitAuthorization(
context.Background(), authzChal.URI)
if err != nil {
revoke(client, authzUrls)
err = &errortypes.RequestError{
errors.Wrap(err, "acme: Authorization wait failed"),
}
return
}
if chal != nil {
err = chal.Remove(db)
if err != nil {
revoke(client, authzUrls)
return
}
}
}
order, err = client.WaitOrder(context.Background(), order.URI)
if err != nil {
revoke(client, authzUrls)
err = &errortypes.RequestError{
errors.Wrap(err, "acme: Order wait failed"),
}
return
}
if order.Status != acme.StatusReady {
err = &errortypes.RequestError{
errors.Newf(
"acme: Authorize order status '%s' not ready",
order.Status,
),
}
return
}
err = create(db, cert, client, order)
if err != nil {
return
}
return
}
func create(db *database.Database, cert *certificate.Certificate,
client *acme.Client, order *acme.Order) (err error) {
var csr []byte
var keyPem []byte
if settings.System.AcmeKeyAlgorithm == "ec" {
csr, keyPem, err = newEcCsr(cert.AcmeDomains)
if err != nil {
return
}
} else {
csr, keyPem, err = newRsaCsr(cert.AcmeDomains)
if err != nil {
return
}
}
derChain, _, err := client.CreateOrderCert(
context.Background(),
order.FinalizeURL,
csr,
true,
)
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "acme: Create order cert failed"),
}
return
}
certPem := ""
for _, der := range derChain {
certBlock := &pem.Block{
Type: "CERTIFICATE",
Bytes: der,
}
if certPem != "" {
certPem += "\n"
}
certPem += strings.TrimSpace(string(pem.EncodeToMemory(certBlock)))
}
cert.Key = strings.TrimSpace(string(keyPem))
cert.Certificate = certPem
cert.AcmeHash = cert.Hash()
_, err = cert.Validate(db)
if err != nil {
return
}
err = cert.CommitFields(db, set.NewSet(
"key", "certificate", "acme_hash", "info"))
if err != nil {
return
}
event.PublishDispatch(db, "certificate.change")
return
}
func Renew(db *database.Database, cert *certificate.Certificate, force bool) (
err error) {
if cert.Type != certificate.LetsEncrypt {
return
}
if force || cert.AcmeHash != cert.Hash() || (cert.Info != nil &&
!cert.Info.ExpiresOn.IsZero() &&
time.Until(cert.Info.ExpiresOn) < 168*time.Hour) {
err = Generate(db, cert)
if err != nil {
return
}
}
return
}
func RenewBackground(cert *certificate.Certificate, force bool) {
go func() {
db := database.GetDatabase()
defer db.Close()
err := Renew(db, cert, force)
if err != nil {
logrus.WithFields(logrus.Fields{
"certificate_id": cert.Id.Hex(),
"certificate_name": cert.Name,
"error": err,
}).Error("task: Failed to renew certificate")
}
}()
}
================================================
FILE: acme/challenge.go
================================================
package acme
import (
"time"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/event"
)
type Challenge struct {
Id string `bson:"_id"`
Resource string `bson:"resource"`
Timestamp time.Time `bson:"timestamp"`
}
func (c *Challenge) Insert(db *database.Database) (err error) {
coll := db.AcmeChallenges()
_, err = coll.InsertOne(db, c)
if err != nil {
err = database.ParseError(err)
return
}
return
}
func (c *Challenge) Remove(db *database.Database) (err error) {
coll := db.AcmeChallenges()
_, err = coll.DeleteOne(db, &bson.M{
"_id": c.Id,
})
if err != nil {
err = database.ParseError(err)
switch err.(type) {
case *database.NotFoundError:
err = nil
default:
return
}
}
return
}
type ChallengeMsg struct {
Token string `bson:"token" json:"token"`
Response string `bson:"response" json:"response"`
}
func (c *ChallengeMsg) Publish(db *database.Database) (err error) {
err = event.Publish(db, "acme", c)
if err != nil {
return
}
return
}
================================================
FILE: acme/constants.go
================================================
package acme
const (
AcmeDirectory = "https://acme-v02.api.letsencrypt.org/directory"
AcmePath = "/.well-known/acme-challenge/"
)
================================================
FILE: acme/utils.go
================================================
package acme
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"net"
"strings"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/settings"
"golang.org/x/crypto/acme"
)
func revoke(client *acme.Client, authzUrls []string) {
if authzUrls == nil {
return
}
for _, authzUrl := range authzUrls {
authz, err := client.GetAuthorization(
context.Background(), authzUrl)
if err != nil {
continue
}
if authz.Status != acme.StatusPending {
continue
}
_ = client.RevokeAuthorization(context.Background(), authzUrl)
}
}
func ParsePath(path string) string {
split := strings.SplitN(path, AcmePath, 2)
if len(split) == 2 {
return split[1]
}
return ""
}
func DnsTxtWait(domain, val string) (found bool, err error) {
start := time.Now()
iterDelay := time.Duration(settings.Acme.DnsRetryRate) * time.Second
timeout := time.Duration(settings.Acme.DnsTimeout) * time.Second
for i := 0; i < 60; i++ {
if time.Since(start) > timeout {
return
}
time.Sleep(iterDelay)
records, e := net.LookupTXT(domain)
if e != nil {
continue
}
for _, record := range records {
if record == val {
found = true
return
}
}
}
return
}
func GetChallenge(token string) (challenge *Challenge, err error) {
db := database.GetDatabase()
defer db.Close()
coll := db.AcmeChallenges()
challenge = &Challenge{}
err = coll.FindOneId(token, challenge)
if err != nil {
return
}
return
}
func newRsaCsr(domains []string) (csr []byte, keyPem []byte, err error) {
key, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "acme: Failed to generate private key"),
}
return
}
csrReq := &x509.CertificateRequest{
SignatureAlgorithm: x509.SHA256WithRSA,
PublicKeyAlgorithm: x509.RSA,
PublicKey: key.Public(),
Subject: pkix.Name{
CommonName: domains[0],
},
DNSNames: domains,
}
csr, err = x509.CreateCertificateRequest(rand.Reader, csrReq, key)
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "acme: Failed to create certificate request"),
}
return
}
certKeyByte := x509.MarshalPKCS1PrivateKey(key)
certKeyBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: certKeyByte,
}
keyPem = pem.EncodeToMemory(certKeyBlock)
return
}
func newEcCsr(domains []string) (csr []byte, keyPem []byte, err error) {
key, err := ecdsa.GenerateKey(
elliptic.P384(),
rand.Reader,
)
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "acme: Failed to generate private key"),
}
return
}
csrReq := &x509.CertificateRequest{
SignatureAlgorithm: x509.ECDSAWithSHA256,
PublicKeyAlgorithm: x509.ECDSA,
PublicKey: key.Public(),
Subject: pkix.Name{
CommonName: domains[0],
},
DNSNames: domains,
}
csr, err = x509.CreateCertificateRequest(rand.Reader, csrReq, key)
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "acme: Failed to create certificate request"),
}
return
}
certKeyByte, err := x509.MarshalECPrivateKey(key)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "acme: Failed to parse private key"),
}
return
}
certKeyBlock := &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: certKeyByte,
}
keyPem = pem.EncodeToMemory(certKeyBlock)
return
}
================================================
FILE: advisory/advisory.go
================================================
package advisory
import (
"net/http"
"time"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/mongo-go-driver/v2/mongo/options"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/settings"
)
var client = &http.Client{
Timeout: 10 * time.Second,
}
type Advisory struct {
Id string `bson:"id" json:"id"`
Timestamp time.Time `bson:"timestamp" json:"timestamp"`
Status string `bson:"status" json:"status"`
Description string `bson:"description" json:"description"`
Score float64 `bson:"score" json:"score"`
Severity string `bson:"severity" json:"severity"`
Vector string `bson:"vector" json:"vector"`
Complexity string `bson:"complexity" json:"complexity"`
Privileges string `bson:"privileges" json:"privileges"`
Interaction string `bson:"interaction" json:"interaction"`
Scope string `bson:"scope" json:"scope"`
Confidentiality string `bson:"confidentiality" json:"confidentiality"`
Integrity string `bson:"integrity" json:"integrity"`
Availability string `bson:"availability" json:"availability"`
}
func (a *Advisory) Validate(db *database.Database) (
errData *errortypes.ErrorData, err error) {
if a.Id == "" {
errData = &errortypes.ErrorData{
Error: "id_required",
Message: "Missing required advisory ID",
}
return
}
if a.Timestamp.IsZero() {
a.Timestamp = time.Now()
}
if !cveIdReg.MatchString(a.Id) {
errData = &errortypes.ErrorData{
Error: "id_invalid",
Message: "Invalid advisory ID",
}
return
}
if a.Status != "" && !ValidStatuses.Contains(a.Status) {
errData = &errortypes.ErrorData{
Error: "invalid_status",
Message: "Invalid advisory status",
}
return
}
if a.Score < 0 || a.Score > 10 {
errData = &errortypes.ErrorData{
Error: "invalid_score",
Message: "Advisory score must be between 0 and 10",
}
return
}
if a.Severity != "" && !ValidSeverities.Contains(a.Severity) {
errData = &errortypes.ErrorData{
Error: "invalid_severity",
Message: "Invalid advisory severity",
}
return
}
if a.Vector != "" && !ValidVectors.Contains(a.Vector) {
errData = &errortypes.ErrorData{
Error: "invalid_vector",
Message: "Invalid advisory attack vector",
}
return
}
if a.Complexity != "" && !ValidComplexities.Contains(a.Complexity) {
errData = &errortypes.ErrorData{
Error: "invalid_complexity",
Message: "Invalid advisory attack complexity",
}
return
}
if a.Privileges != "" && !ValidPrivileges.Contains(a.Privileges) {
errData = &errortypes.ErrorData{
Error: "invalid_privileges",
Message: "Invalid advisory privileges required",
}
return
}
if a.Interaction != "" && !ValidInteractions.Contains(a.Interaction) {
errData = &errortypes.ErrorData{
Error: "invalid_interaction",
Message: "Invalid advisory user interaction",
}
return
}
if a.Scope != "" && !ValidScopes.Contains(a.Scope) {
errData = &errortypes.ErrorData{
Error: "invalid_scope",
Message: "Invalid advisory scope",
}
return
}
if a.Confidentiality != "" &&
!ValidImpacts.Contains(a.Confidentiality) {
errData = &errortypes.ErrorData{
Error: "invalid_confidentiality",
Message: "Invalid advisory confidentiality impact",
}
return
}
if a.Integrity != "" && !ValidImpacts.Contains(a.Integrity) {
errData = &errortypes.ErrorData{
Error: "invalid_integrity",
Message: "Invalid advisory integrity impact",
}
return
}
if a.Availability != "" && !ValidImpacts.Contains(a.Availability) {
errData = &errortypes.ErrorData{
Error: "invalid_availability",
Message: "Invalid advisory availability impact",
}
return
}
return
}
func (a *Advisory) IsFresh() bool {
if a == nil {
return false
}
if (a.Status == Analyzed || a.Status == Deferred) &&
time.Since(a.Timestamp) < time.Duration(
settings.Telemetry.NvdFinalTtl)*time.Second {
return true
}
if time.Since(a.Timestamp) < time.Duration(
settings.Telemetry.NvdTtl)*time.Second {
return true
}
return false
}
func (a *Advisory) Commit(db *database.Database) (err error) {
coll := db.Advisories()
_, err = coll.UpdateOne(
db,
&bson.M{
"_id": a.Id,
},
&bson.M{
"$set": &bson.M{
"timestamp": a.Timestamp,
"status": a.Status,
"description": a.Description,
"score": a.Score,
"severity": a.Severity,
"vector": a.Vector,
"complexity": a.Complexity,
"privileges": a.Privileges,
"interaction": a.Interaction,
"scope": a.Scope,
"confidentiality": a.Confidentiality,
"integrity": a.Integrity,
"availability": a.Availability,
},
},
options.UpdateOne().SetUpsert(true),
)
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: advisory/constants.go
================================================
package advisory
import (
"regexp"
"github.com/dropbox/godropbox/container/set"
)
const (
None = "none"
Low = "low"
Medium = "medium"
High = "high"
Critical = "critical"
Network = "network"
Adjacent = "adjacent"
Local = "local"
Physical = "physical"
Required = "required"
Unchanged = "unchanged"
Changed = "changed"
Analyzed = "analyzed"
AwaitingAnalysis = "awaiting_analysis"
Rejected = "rejected"
Undergoing = "undergoing_analysis"
Modified = "modified"
Deferred = "deferred"
Pending = "pending"
nvdApi = "https://services.nvd.nist.gov/rest/json/cves/2.0"
)
var (
cveIdReg = regexp.MustCompile(`^CVE-\d{4}-\d{4,}$`)
ValidStatuses = set.NewSet(
Analyzed,
AwaitingAnalysis,
Rejected,
Undergoing,
Modified,
Deferred,
)
ValidSeverities = set.NewSet(
None,
Low,
Medium,
High,
Critical,
)
ValidVectors = set.NewSet(
Network,
Adjacent,
Local,
Physical,
)
ValidComplexities = set.NewSet(
Low,
High,
)
ValidPrivileges = set.NewSet(
None,
Low,
High,
)
ValidInteractions = set.NewSet(
None,
Required,
)
ValidScopes = set.NewSet(
Unchanged,
Changed,
)
ValidImpacts = set.NewSet(
None,
Low,
High,
)
)
================================================
FILE: advisory/utils.go
================================================
package advisory
import (
"encoding/json"
"net/http"
"strings"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/settings"
)
var (
lastCall time.Time
)
type nvdCvssData struct {
VectorString string `json:"vectorString"`
BaseScore float64 `json:"baseScore"`
BaseSeverity string `json:"baseSeverity"`
AttackVector string `json:"attackVector"`
AttackComplexity string `json:"attackComplexity"`
PrivilegesRequired string `json:"privilegesRequired"`
UserInteraction string `json:"userInteraction"`
Scope string `json:"scope"`
ConfidentialityImpact string `json:"confidentialityImpact"`
IntegrityImpact string `json:"integrityImpact"`
AvailabilityImpact string `json:"availabilityImpact"`
}
type nvdCvssMetric struct {
Type string `json:"type"`
CvssData nvdCvssData `json:"cvssData"`
}
type nvdMetrics struct {
CvssMetricV31 []nvdCvssMetric `json:"cvssMetricV31"`
}
type nvdDescription struct {
Lang string `json:"lang"`
Value string `json:"value"`
}
type nvdCve struct {
ID string `json:"id"`
VulnStatus string `json:"vulnStatus"`
Descriptions []nvdDescription `json:"descriptions"`
Metrics nvdMetrics `json:"metrics"`
}
type nvdVulnerability struct {
Cve nvdCve `json:"cve"`
}
type nvdResponse struct {
TotalResults int `json:"totalResults"`
Vulnerabilities []nvdVulnerability `json:"vulnerabilities"`
}
func normalizeStatus(status string) string {
switch status {
case "Analyzed":
return Analyzed
case "Awaiting Analysis":
return AwaitingAnalysis
case "Rejected":
return Rejected
case "Undergoing Analysis":
return Undergoing
case "Modified":
return Modified
case "Deferred":
return Deferred
default:
return strings.ToLower(strings.ReplaceAll(status, " ", "_"))
}
}
func normalizeValue(val string) string {
switch strings.ToUpper(val) {
case "NONE":
return None
case "LOW":
return Low
case "MEDIUM":
return Medium
case "HIGH":
return High
case "CRITICAL":
return Critical
case "NETWORK":
return Network
case "ADJACENT_NETWORK", "ADJACENT":
return Adjacent
case "LOCAL":
return Local
case "PHYSICAL":
return Physical
case "REQUIRED":
return Required
case "UNCHANGED":
return Unchanged
case "CHANGED":
return Changed
default:
return strings.ToLower(val)
}
}
func getOne(db *database.Database, query *bson.M) (adv *Advisory, err error) {
coll := db.Advisories()
adv = &Advisory{}
err = coll.FindOne(db, query).Decode(adv)
if err != nil {
err = database.ParseError(err)
return
}
return
}
func getOneNvd(db *database.Database, cveId string) (
adv *Advisory, err error) {
req, err := http.NewRequest("GET", nvdApi, nil)
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "advisory: Failed to create request"),
}
return
}
query := req.URL.Query()
query.Set("cveId", cveId)
req.URL.RawQuery = query.Encode()
nvdApiKey := settings.Telemetry.NvdApiKey
if nvdApiKey != "" {
req.Header.Set("apiKey", nvdApiKey)
}
resp, err := client.Do(req)
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "advisory: Request failed"),
}
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = &errortypes.RequestError{
errors.Newf("advisory: Bad status status %d", resp.StatusCode),
}
return
}
nvdResp := &nvdResponse{}
err = json.NewDecoder(resp.Body).Decode(nvdResp)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "advisory: Failed to decode response"),
}
return
}
if nvdResp.TotalResults == 0 || len(nvdResp.Vulnerabilities) == 0 {
err = &errortypes.NotFoundError{
errors.New("advisory: Not found"),
}
return
}
cve := nvdResp.Vulnerabilities[0].Cve
adv = &Advisory{
Id: strings.ToUpper(cve.ID),
Timestamp: time.Now(),
Status: normalizeStatus(cve.VulnStatus),
}
for _, desc := range cve.Descriptions {
if desc.Lang == "en" {
adv.Description = desc.Value
break
}
}
metrics := cve.Metrics.CvssMetricV31
if len(metrics) > 0 {
var cvss *nvdCvssMetric
for i := range metrics {
if metrics[i].Type == "Primary" {
cvss = &metrics[i]
break
}
}
if cvss == nil {
cvss = &metrics[0]
}
adv.Score = cvss.CvssData.BaseScore
adv.Severity = normalizeValue(cvss.CvssData.BaseSeverity)
adv.Vector = normalizeValue(cvss.CvssData.AttackVector)
adv.Complexity = normalizeValue(cvss.CvssData.AttackComplexity)
adv.Privileges = normalizeValue(cvss.CvssData.PrivilegesRequired)
adv.Interaction = normalizeValue(cvss.CvssData.UserInteraction)
adv.Scope = normalizeValue(cvss.CvssData.Scope)
adv.Confidentiality = normalizeValue(
cvss.CvssData.ConfidentialityImpact)
adv.Integrity = normalizeValue(cvss.CvssData.IntegrityImpact)
adv.Availability = normalizeValue(cvss.CvssData.AvailabilityImpact)
}
errData, err := adv.Validate(db)
if err != nil {
return
}
if errData != nil {
err = errData.GetError()
return
}
err = adv.Commit(db)
if err != nil {
return
}
return
}
func GetOneLimit(db *database.Database, cveId string) (
adv *Advisory, err error) {
adv, err = getOne(db, &bson.M{
"_id": cveId,
})
if err != nil {
if _, ok := err.(*database.NotFoundError); ok {
adv = nil
} else {
return
}
}
if adv.IsFresh() {
return
}
since := time.Since(lastCall)
var limit time.Duration
if settings.Telemetry.NvdApiKey != "" {
limit = time.Duration(settings.Telemetry.NvdApiAuthLimit) * time.Second
} else {
limit = time.Duration(settings.Telemetry.NvdApiLimit) * time.Second
}
if since < limit {
time.Sleep(limit - since)
}
lastCall = time.Now()
adv, err = getOneNvd(db, cveId)
if err != nil {
return
}
return
}
func GetOne(db *database.Database, cveId string) (adv *Advisory, err error) {
adv, err = getOne(db, &bson.M{
"_id": cveId,
})
if err != nil {
if _, ok := err.(*database.NotFoundError); ok {
adv = nil
} else {
return
}
}
if adv.IsFresh() {
return
}
adv, err = getOneNvd(db, cveId)
if err != nil {
return
}
return
}
func Remove(db *database.Database, advId bson.ObjectID) (err error) {
coll := db.Advisories()
_, err = coll.DeleteOne(db, &bson.M{
"_id": advId,
})
if err != nil {
err = database.ParseError(err)
if _, ok := err.(*database.NotFoundError); ok {
err = nil
} else {
return
}
}
return
}
================================================
FILE: agent/agent.go
================================================
package main
import (
"flag"
"fmt"
"os"
"runtime/debug"
"strings"
"syscall"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/agent/constants"
"github.com/pritunl/pritunl-cloud/agent/imds"
"github.com/pritunl/pritunl-cloud/agent/utils"
"github.com/pritunl/pritunl-cloud/engine"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/imds/types"
pritunl_utils "github.com/pritunl/pritunl-cloud/utils"
"github.com/pritunl/tools/logger"
)
const help = `
Usage: pci COMMAND
Commands:
get Get value from IMDS
image Sanitize host files and initiate shutdown for imaging
version Show version
`
var (
daemon = flag.Bool("daemon", false, "Fork agent to background")
)
func main() {
defer func() {
panc := recover()
if panc != nil {
logger.WithFields(logger.Fields{
"trace": string(debug.Stack()),
"panic": panc,
}).Error("agent: Panic in main")
time.Sleep(3 * time.Second)
os.Exit(1)
}
}()
flag.Usage = func() {
fmt.Printf(help)
}
flag.Parse()
logger.Init(
logger.SetTimeFormat(""),
)
logger.AddHandler(func(record *logger.Record) {
fmt.Print(record.String())
})
command := flag.Arg(0)
if command == "engine" || command == "agent" {
envStateData := os.Getenv("IMDS_STATE")
envStateDatas := strings.Split(envStateData, ":")
if len(envStateDatas) != 2 {
fmt.Println("pritunl-cloud-agent: Invalid state")
os.Exit(1)
return
}
stage := envStateDatas[0]
envState := envStateDatas[1]
if stage == "run" {
err := imds.SetState(envState)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to write imds state")
utils.DelayExit(1, 1*time.Second)
return
}
} else {
confState := imds.GetState()
if envState != "" && confState != envState {
fmt.Println("pritunl-cloud-agent: Waiting for state")
os.Exit(0)
return
}
}
if *daemon {
err := daemonFork()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to fork to background")
utils.DelayExit(1, 1*time.Second)
return
}
}
}
switch command {
case "get":
ids := &imds.Imds{}
err := ids.Init(nil)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Initialize failed")
utils.DelayExit(1, 1*time.Second)
return
}
defer ids.Close()
val, err := ids.Get(flag.Arg(1))
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Get imds failed")
utils.DelayExit(1, 1*time.Second)
return
}
fmt.Print(val)
break
case "engine":
eng := &engine.Engine{
OnStatus: imds.SetStatus,
}
ids := &imds.Imds{}
err := ids.Init(eng)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to init imds")
utils.DelayExit(1, 1*time.Second)
return
}
defer ids.Close()
err = ids.OpenLog()
if err != nil {
return
}
err = ids.SyncReady(5 * time.Minute)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to sync imds initial")
utils.DelayExit(1, 1*time.Second)
return
}
image := false
phase := engine.Reboot
switch flag.Arg(1) {
case engine.Image:
image = true
phase = engine.Initial
break
case engine.Initial:
phase = engine.Initial
break
}
err = eng.Init()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to init engine")
utils.DelayExit(1, 1*time.Second)
return
}
data, err := utils.Read("/etc/pritunl-deploy.md")
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to read deploy spec")
utils.DelayExit(1, 1*time.Second)
return
}
blocks, err := engine.Parse(data)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to parse deploy spec")
utils.DelayExit(1, 1*time.Second)
return
}
ids.RunSync(image)
runStatus := types.Running
fatal, err := eng.Run(phase, blocks)
if err != nil {
runStatus = types.Fault
if fatal {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Fatal initial engine run error")
utils.DelayExit(1, 1*time.Second)
return
} else {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Non-fatal initial engine run error")
err = nil
}
}
if !image {
ids.SetInitialized()
err = ids.SyncStatus(runStatus)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to sync status")
utils.DelayExit(1, 1*time.Second)
return
}
err = ids.Wait()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to run")
utils.DelayExit(1, 1*time.Second)
return
}
}
time.Sleep(500 * time.Millisecond)
_, err = ids.Sync()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to sync")
utils.DelayExit(1, 1*time.Second)
return
}
break
case "agent":
ids := &imds.Imds{}
err := ids.Init(nil)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to init imds")
utils.DelayExit(1, 1*time.Second)
return
}
defer ids.Close()
err = ids.OpenLog()
if err != nil {
return
}
err = ids.SyncReady(5 * time.Minute)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to sync imds initial")
utils.DelayExit(1, 1*time.Second)
return
}
ids.RunSync(false)
ids.SetInitialized()
err = ids.SyncStatus(types.Running)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to sync status")
utils.DelayExit(1, 1*time.Second)
return
}
err = ids.Wait()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to run")
utils.DelayExit(1, 1*time.Second)
return
}
time.Sleep(500 * time.Millisecond)
_, err = ids.Sync()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to sync")
utils.DelayExit(1, 1*time.Second)
return
}
break
case "image":
ids := &imds.Imds{}
err := ids.Init(nil)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Iniatilize failed")
utils.DelayExit(1, 1*time.Second)
return
}
err = utils.Sanitize()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Sanitize failed")
utils.DelayExit(1, 1*time.Second)
return
}
err = ids.SyncStatus(types.Imaged)
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Sync status failed")
utils.DelayExit(1, 1*time.Second)
return
}
err = utils.SanitizeImds()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Sanitize imds failed")
utils.DelayExit(1, 1*time.Second)
return
}
break
case "status":
mem, err := pritunl_utils.GetMemInfo()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("imds: Failed to get memory")
utils.DelayExit(1, 1*time.Second)
return
}
fmt.Println("Memory Information:")
fmt.Printf(" Total Memory: %d KB\n", mem.Total)
fmt.Printf(" Free Memory: %d KB\n", mem.Free)
fmt.Printf(" Available Memory: %d KB\n", mem.Available)
fmt.Printf(" Buffers: %d KB\n", mem.Buffers)
fmt.Printf(" Cached: %d KB\n", mem.Cached)
fmt.Printf(" Used Memory: %d KB\n", mem.Used)
fmt.Printf(" Used Percentage: %.2f%%\n", mem.UsedPercent)
fmt.Printf(" Dirty: %d KB\n", mem.Dirty)
fmt.Println("\nSwap Information:")
fmt.Printf(" Swap Total: %d KB\n", mem.SwapTotal)
fmt.Printf(" Swap Free: %d KB\n", mem.SwapFree)
fmt.Printf(" Swap Used: %d KB\n", mem.SwapUsed)
fmt.Printf(" Swap Used Percentage: %.2f%%\n", mem.SwapUsedPercent)
fmt.Println("\nHugePages Information:")
fmt.Printf(" HugePages Total: %d\n", mem.HugePagesTotal)
fmt.Printf(" HugePages Free: %d\n", mem.HugePagesFree)
fmt.Printf(" HugePages Reserved: %d\n", mem.HugePagesReserved)
fmt.Printf(" HugePages Used: %d\n", mem.HugePagesUsed)
fmt.Printf(" HugePages Used Percent: %.2f%%\n", mem.HugePagesUsedPercent)
fmt.Printf(" HugePage Size: %d KB\n", mem.HugePageSize)
load, err := pritunl_utils.LoadAverage()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("imds: Failed to get load")
utils.DelayExit(1, 1*time.Second)
return
}
fmt.Println("\nLoad Average Information:")
fmt.Printf(" CPU Units: %d\n", load.CpuUnits)
fmt.Printf(" Load Average (1 min): %.2f%%\n", load.Load1)
fmt.Printf(" Load Average (5 min): %.2f%%\n", load.Load5)
fmt.Printf(" Load Average (15 min): %.2f%%\n", load.Load15)
break
case "version":
fmt.Printf("pci v%s\n", constants.Version)
break
default:
fmt.Printf(help)
}
return
}
func daemonFork() (err error) {
fmt.Println("pritunl-cloud-agent: Forking daemon process")
app, err := os.Executable()
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "agent: Failed to get executable path"),
}
return
}
args := []string{app}
args = append(args, flag.Args()...)
devNull, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
if err != nil {
err = &errortypes.WriteError{
errors.Wrap(err, "agent: Failed to open /dev/null"),
}
return
}
_, err = os.StartProcess(app, args, &os.ProcAttr{
Files: []*os.File{nil, devNull, devNull},
Sys: &syscall.SysProcAttr{
Setsid: true,
},
})
if err != nil {
devNull.Close()
err = &errortypes.ExecError{
errors.Wrap(err, "agent: Failed to fork agent process"),
}
return
}
os.Exit(0)
return
}
================================================
FILE: agent/constants/constants.go
================================================
package constants
const (
Version = "1.0.3248.95"
ImdsConfPath = "/etc/pritunl-imds.json"
ImdsLogPath = "/var/log/pritunl-imds.log"
)
================================================
FILE: agent/imds/imds.go
================================================
package imds
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"runtime/debug"
"strings"
"sync"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/agent/constants"
"github.com/pritunl/pritunl-cloud/agent/logging"
"github.com/pritunl/pritunl-cloud/engine"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/imds/types"
"github.com/pritunl/pritunl-cloud/telemetry"
"github.com/pritunl/pritunl-cloud/utils"
"github.com/pritunl/tools/logger"
"github.com/pritunl/tools/set"
)
var (
client = &http.Client{
Timeout: 10 * time.Second,
}
curSyncHash uint32
)
type Imds struct {
Address string `json:"address"`
Port int `json:"port"`
Secret string `json:"secret"`
State string `json:"state"`
engine *engine.Engine `json:"-"`
initialized bool `json:"-"`
waiter sync.WaitGroup `json:"-"`
journals map[string]*Journal `json:"-"`
syncLock sync.Mutex `json:"-"`
logger *logging.Redirect `json:"-"`
}
func (m *Imds) NewRequest(method, pth string, data interface{}) (
req *http.Request, err error) {
u := &url.URL{}
u.Scheme = "http"
u.Host = fmt.Sprintf("%s:%d", m.Address, m.Port)
u.Path = pth
var body io.Reader
if data != nil {
reqDataBuf := &bytes.Buffer{}
err = json.NewEncoder(reqDataBuf).Encode(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "agent: Failed to parse request data"),
}
return
}
body = reqDataBuf
}
req, err = http.NewRequest(method, u.String(), body)
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "agent: Failed to create imds request"),
}
return
}
req.Header.Set("User-Agent", "pritunl-imds")
req.Header.Set("Auth-Token", m.Secret)
if data != nil {
req.Header.Set("Content-Type", "application/json")
}
return
}
func (m *Imds) Get(query string) (val string, err error) {
query = strings.TrimPrefix(query, "+")
req, err := m.NewRequest("GET", "/query"+query, nil)
resp, e := client.Do(req)
if e != nil {
err = &errortypes.RequestError{
errors.Wrap(e, "agent: Imds request failed"),
}
return
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
body := ""
data, _ := ioutil.ReadAll(resp.Body)
if data != nil {
body = string(data)
}
errData := &errortypes.ErrorData{}
err = json.Unmarshal(data, errData)
if err != nil || errData.Error == "" {
errData = nil
}
if errData != nil && errData.Message != "" {
body = errData.Message
}
err = &errortypes.RequestError{
errors.Newf(
"agent: Imds server get error %d - %s",
resp.StatusCode, body),
}
return
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "agent: Imds failed to read body"),
}
return
}
val = string(data)
return
}
type SyncResp struct {
Spec string `json:"spec"`
Hash uint32 `json:"hash"`
Journals []*types.Journal `json:"journals"`
}
func (m *Imds) SyncReady(timeout time.Duration) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
ticker := time.NewTicker(200 * time.Millisecond)
defer ticker.Stop()
var lastErr error
for {
select {
case <-ctx.Done():
if lastErr != nil {
err = lastErr
} else {
err = &errortypes.RequestError{
errors.New("agent: Initial config timeout"),
}
}
return
case <-ticker.C:
ready, e := m.Sync()
if e != nil {
lastErr = e
continue
}
if !ready {
continue
}
return nil
}
}
}
func (m *Imds) Sync() (ready bool, err error) {
m.syncLock.Lock()
defer m.syncLock.Unlock()
data, err := m.GetState(curSyncHash)
if err != nil {
return
}
if m.logger != nil {
data.Output = m.logger.GetOutput()
}
if m.journals != nil {
journals := map[string][]*types.Entry{}
for _, jrnl := range m.journals {
journals[jrnl.Key] = jrnl.Handler.GetOutput()
}
if len(journals) > 0 {
data.Journals = journals
}
} else {
m.journals = map[string]*Journal{}
}
req, err := m.NewRequest("PUT", "/sync", data)
if err != nil {
return
}
resp, err := client.Do(req)
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "agent: Imds request failed"),
}
return
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
body := ""
data, _ := ioutil.ReadAll(resp.Body)
if data != nil {
body = string(data)
}
errData := &errortypes.ErrorData{}
err = json.Unmarshal(data, errData)
if err != nil || errData.Error == "" {
errData = nil
}
if errData != nil && errData.Message != "" {
body = errData.Message
}
err = &errortypes.RequestError{
errors.Newf("agent: Imds server sync error %d - %s",
resp.StatusCode, body),
}
return
}
respData := &SyncResp{}
err = json.NewDecoder(resp.Body).Decode(respData)
if err != nil {
err = &errortypes.RequestError{
errors.Wrap(err, "agent: Failed to decode imds sync resp"),
}
return
}
ready = true
if respData.Hash == 0 {
ready = false
} else if curSyncHash == 0 {
curSyncHash = respData.Hash
} else if respData.Hash != curSyncHash && respData.Spec != "" &&
m.engine != nil && m.initialized {
curSyncHash = respData.Hash
logger.WithFields(logger.Fields{
"spec_len": len(respData.Spec),
"hash": int(respData.Hash),
}).Info("agent: Queuing engine reload")
m.engine.Queue(respData.Spec)
}
activeJournals := set.NewSet()
for unit := range m.journals {
activeJournals.Add(unit)
}
for _, jrnlConf := range respData.Journals {
if activeJournals.Contains(jrnlConf.Key) {
activeJournals.Remove(jrnlConf.Key)
jrnl := m.journals[jrnlConf.Key]
if jrnl != nil {
if jrnl.Index != jrnlConf.Index ||
jrnl.Key != jrnlConf.Key ||
jrnl.Type != jrnlConf.Type ||
jrnl.Unit != jrnlConf.Unit ||
jrnl.Path != jrnlConf.Path {
jrnl.Close()
delete(m.journals, jrnlConf.Key)
} else {
continue
}
}
}
jrnl := &Journal{
Index: jrnlConf.Index,
Key: jrnlConf.Key,
Type: jrnlConf.Type,
Unit: jrnlConf.Unit,
Path: jrnlConf.Path,
}
if jrnl.Type == "file" {
jrnl.Handler = logging.NewFile(jrnlConf.Path)
} else if jrnl.Type == "systemd" {
jrnl.Handler = logging.NewSystemd(jrnlConf.Unit)
} else {
continue
}
err = jrnl.Open()
if err != nil {
return
}
m.journals[jrnlConf.Key] = jrnl
}
for jrnlKeyInf := range activeJournals.Iter() {
jrnlKey := jrnlKeyInf.(string)
jrnl := m.journals[jrnlKey]
if jrnl != nil {
jrnl.Close()
delete(m.journals, jrnlKey)
}
}
return
}
func (m *Imds) SetInitialized() {
m.initialized = true
if m.engine != nil {
m.engine.StartRunner()
}
}
func (m *Imds) RunSync(fast bool) {
m.waiter.Add(1)
go func() {
defer func() {
panc := recover()
if panc != nil {
logger.WithFields(logger.Fields{
"trace": string(debug.Stack()),
"panic": panc,
}).Error("sync: Panic in telemetry")
}
}()
for {
telemetry.Refresh()
time.Sleep(1 * time.Minute)
}
}()
go func() {
defer m.waiter.Done()
for {
func() {
defer func() {
panc := recover()
if panc != nil {
logger.WithFields(logger.Fields{
"trace": string(debug.Stack()),
"panic": panc,
}).Error("agent: Panic in sync")
time.Sleep(3 * time.Second)
os.Exit(1)
}
}()
_, err := m.Sync()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Error("agent: Failed to sync")
}
}()
if fast {
time.Sleep(500 * time.Millisecond)
} else {
time.Sleep(1 * time.Second)
}
}
}()
}
func (m *Imds) SyncStatus(status string) (err error) {
SetStatus(status)
_, err = m.Sync()
if err != nil {
logger.WithFields(logger.Fields{
"status": status,
"error": err,
}).Error("agent: Failed to sync status")
}
return
}
func (m *Imds) Wait() (err error) {
m.waiter.Wait()
return
}
func (m *Imds) Init(eng *engine.Engine) (err error) {
m.engine = eng
confData, err := utils.Read(constants.ImdsConfPath)
if err != nil {
return
}
err = json.Unmarshal([]byte(confData), m)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "agent: Failed to unmarshal imds conf"),
}
return
}
return
}
func (m *Imds) OpenLog() (err error) {
m.logger = &logging.Redirect{}
err = m.logger.Open()
if err != nil {
return
}
return
}
func (m *Imds) Close() {
if m.logger != nil {
m.logger.Close()
}
}
================================================
FILE: agent/imds/journal.go
================================================
package imds
import (
"github.com/pritunl/pritunl-cloud/agent/logging"
"github.com/pritunl/tools/logger"
)
type Journal struct {
Index int32 `json:"-"`
Key string `json:"-"`
Type string `json:"-"`
Unit string `json:"-"`
Path string `json:"-"`
Handler logging.Handler `json:"-"`
}
func (j *Journal) Open() (err error) {
logger.WithFields(logger.Fields{
"index": j.Index,
"key": j.Key,
"type": j.Type,
"unit": j.Unit,
"path": j.Path,
}).Info("agent: Starting journal")
err = j.Handler.Open()
if err != nil {
return
}
return
}
func (j *Journal) Close() {
logger.WithFields(logger.Fields{
"index": j.Index,
"key": j.Key,
"type": j.Type,
"unit": j.Unit,
"path": j.Path,
}).Info("agent: Stopping journal")
err := j.Handler.Close()
if err != nil {
logger.WithFields(logger.Fields{
"index": j.Index,
"key": j.Key,
"type": j.Type,
"unit": j.Unit,
"path": j.Path,
"error": err,
}).Error("agent: Error stopping journal")
}
return
}
================================================
FILE: agent/imds/sync.go
================================================
package imds
import (
"sync"
"time"
"github.com/pritunl/pritunl-cloud/imds/types"
"github.com/pritunl/pritunl-cloud/telemetry"
"github.com/pritunl/pritunl-cloud/utils"
"github.com/pritunl/tools/logger"
)
var (
curStatus = types.Initializing
curStatusLock sync.Mutex
)
type StateData struct {
*types.State
}
func (m *Imds) GetState(curHash uint32) (data *StateData, err error) {
data = &StateData{
&types.State{},
}
data.Hash = curHash
curStatusLock.Lock()
data.Status = curStatus
curStatusLock.Unlock()
mem, err := utils.GetMemInfo()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Limit(30 * time.Minute).Error("imds: Failed to get memory")
} else {
data.Memory = utils.ToFixed(mem.UsedPercent, 2)
data.HugePages = utils.ToFixed(mem.HugePagesUsedPercent, 2)
}
load, err := utils.LoadAverage()
if err != nil {
logger.WithFields(logger.Fields{
"error": err,
}).Limit(30 * time.Minute).Error("imds: Failed to get load")
} else {
data.Load1 = load.Load1
data.Load5 = load.Load5
data.Load15 = load.Load15
}
updates, ok := telemetry.Updates.Get()
if ok {
data.Updates = updates
} else {
data.Updates = nil
}
return
}
func SetStatus(status string) {
curStatusLock.Lock()
curStatus = status
curStatusLock.Unlock()
}
================================================
FILE: agent/imds/utils.go
================================================
package imds
import (
"encoding/json"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/agent/constants"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/utils"
)
func GetState() string {
confData, err := utils.Read(constants.ImdsConfPath)
if err != nil {
return ""
}
conf := &Imds{}
err = json.Unmarshal([]byte(confData), conf)
if err != nil {
return ""
}
return conf.State
}
func SetState(state string) (err error) {
confData, err := utils.Read(constants.ImdsConfPath)
if err != nil {
return
}
conf := &Imds{}
err = json.Unmarshal([]byte(confData), conf)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "agent: Failed to unmarshal imds conf"),
}
return
}
conf.State = state
dataByt, err := json.Marshal(conf)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "agent: Failed to unmarshal imds conf"),
}
return
}
err = utils.Write(constants.ImdsConfPath, string(dataByt), 0600)
if err != nil {
return
}
return
}
================================================
FILE: agent/logging/file.go
================================================
package logging
import (
"bufio"
"context"
"os/exec"
"runtime/debug"
"strings"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/imds/types"
"github.com/pritunl/tools/logger"
)
type File struct {
path string
output chan *types.Entry
cmd *exec.Cmd
ctx context.Context
cancel context.CancelFunc
}
func (f *File) GetOutput() (entries []*types.Entry) {
for {
select {
case entry := <-f.output:
entries = append(entries, entry)
default:
return
}
}
}
func (f *File) followJournal() (err error) {
defer func() {
rec := recover()
if rec != nil {
logger.WithFields(logger.Fields{
"path": f.path,
"panic": rec,
}).Error("agent: File follower panic")
}
}()
f.cmd = exec.CommandContext(f.ctx, "tail",
"-F", f.path,
)
stdout, err := f.cmd.StdoutPipe()
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "agent: Error creating stdout pipe"),
}
return
}
err = f.cmd.Start()
if err != nil {
err = &errortypes.ExecError{
errors.Wrap(err, "agent: Error starting tail"),
}
return
}
scanner := bufio.NewScanner(stdout)
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)
for scanner.Scan() {
select {
case <-f.ctx.Done():
return
default:
}
line := scanner.Text()
timestamp := time.Now()
level := int32(5)
if strings.Contains(strings.ToLower(line), "error") {
level = 3
}
select {
case f.output <- &types.Entry{
Timestamp: timestamp,
Level: level,
Message: line,
}:
default:
}
continue
}
err = scanner.Err()
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "agent: Error reading tail"),
}
return
}
f.cmd.Wait()
return
}
func (f *File) Open() (err error) {
f.output = make(chan *types.Entry, 10000)
f.ctx, f.cancel = context.WithCancel(context.Background())
go func() {
defer func() {
panc := recover()
if panc != nil {
logger.WithFields(logger.Fields{
"trace": string(debug.Stack()),
"panic": panc,
}).Error("sync: Panic in tail open")
}
}()
for {
select {
case <-f.ctx.Done():
return
default:
}
e := f.followJournal()
select {
case <-f.ctx.Done():
return
default:
}
if e != nil {
logger.WithFields(logger.Fields{
"path": f.path,
"error": e,
}).Error("agent: Journal follower error, restarting")
} else {
logger.WithFields(logger.Fields{
"path": f.path,
}).Info("agent: Journal follower exited, restarting")
}
select {
case <-time.After(3 * time.Second):
case <-f.ctx.Done():
return
}
}
}()
return
}
func (f *File) Close() (err error) {
defer func() {
panc := recover()
if panc != nil {
logger.WithFields(logger.Fields{
"trace": string(debug.Stack()),
"panic": panc,
}).Error("sync: Panic in journal close")
}
}()
if f.cancel != nil {
f.cancel()
}
if f.cmd != nil && f.cmd.Process != nil {
f.cmd.Process.Kill()
}
if f.output != nil {
close(f.output)
}
return
}
func NewFile(path string) *File {
return &File{
path: path,
}
}
================================================
FILE: agent/logging/handler.go
================================================
package logging
import (
"github.com/pritunl/pritunl-cloud/imds/types"
)
type Handler interface {
Open() (err error)
Close() (err error)
GetOutput() (entries []*types.Entry)
}
================================================
FILE: agent/logging/logging.go
================================================
package logging
import (
"bufio"
"fmt"
"io"
"os"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/agent/constants"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/imds/types"
)
const maxCapacity = 128 * 1024
type Redirect struct {
file *os.File
writer io.Writer
origStout *os.File
origStderr *os.File
output chan *types.Entry
stdoutReader *os.File
stdoutWriter *os.File
stderrReader *os.File
stderrWriter *os.File
}
func (r *Redirect) GetOutput() (entries []*types.Entry) {
for {
select {
case entry := <-r.output:
entries = append(entries, entry)
default:
return
}
}
}
func (r *Redirect) handleOutput(reader *os.File, level int32) {
scanner := bufio.NewScanner(reader)
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)
for scanner.Scan() {
line := scanner.Text()
timestamp := time.Now()
fmt.Fprintf(
r.writer, "[%s] %s\n",
timestamp.Format("2006-01-02 15:04:05"),
line,
)
select {
case r.output <- &types.Entry{
Timestamp: timestamp,
Level: level,
Message: line,
}:
default:
}
}
}
func (r *Redirect) Open() (err error) {
r.file, err = os.OpenFile(
constants.ImdsLogPath,
os.O_APPEND|os.O_CREATE|os.O_WRONLY,
0600,
)
if err != nil {
err = &errortypes.WriteError{
errors.Wrap(err, "agent: Failed to create log file"),
}
return
}
r.output = make(chan *types.Entry, 10000)
r.writer = io.MultiWriter(r.file, os.Stdout)
r.origStout = os.Stdout
r.origStderr = os.Stderr
r.stdoutReader, r.stdoutWriter, err = os.Pipe()
if err != nil {
err = &errortypes.WriteError{
errors.Wrap(err, "agent: Failed to create stdout pipe"),
}
return
}
r.stderrReader, r.stderrWriter, err = os.Pipe()
if err != nil {
err = &errortypes.WriteError{
errors.Wrap(err, "agent: Failed to create stderr pipe"),
}
return
}
os.Stdout = r.stdoutWriter
os.Stderr = r.stderrWriter
go r.handleOutput(r.stdoutReader, types.Info)
go r.handleOutput(r.stderrReader, types.Error)
return
}
func (r *Redirect) Close() (err error) {
os.Stdout = r.origStout
os.Stderr = r.origStderr
if r.stdoutWriter != nil {
r.stdoutWriter.Close()
}
if r.stdoutReader != nil {
r.stdoutReader.Close()
}
if r.stderrWriter != nil {
r.stderrWriter.Close()
}
if r.stderrReader != nil {
r.stderrReader.Close()
}
err = r.file.Close()
if err != nil {
err = &errortypes.WriteError{
errors.Wrap(err, "agent: Failed to close log pipe"),
}
return
}
return
}
================================================
FILE: agent/logging/systemd.go
================================================
package logging
import (
"bufio"
"context"
"encoding/json"
"os/exec"
"runtime/debug"
"strconv"
"strings"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/imds/types"
"github.com/pritunl/tools/commander"
"github.com/pritunl/tools/logger"
)
type Systemd struct {
unit string
output chan *types.Entry
cmd *exec.Cmd
ctx context.Context
cancel context.CancelFunc
}
type journalEntry struct {
Message string `json:"MESSAGE"`
Priority string `json:"PRIORITY"`
Timestamp string `json:"__REALTIME_TIMESTAMP"`
}
func (s *Systemd) GetOutput() (entries []*types.Entry) {
for {
select {
case entry := <-s.output:
entries = append(entries, entry)
default:
return
}
}
}
func (s *Systemd) followJournal() (err error) {
defer func() {
rec := recover()
if rec != nil {
logger.WithFields(logger.Fields{
"unit": s.unit,
"panic": rec,
}).Error("agent: Journal follower panic")
}
}()
existsTime := time.Time{}
for {
resp, _ := commander.Exec(&commander.Opt{
Name: "systemctl",
Args: []string{
"status",
s.unit,
},
PipeOut: true,
PipeErr: true,
})
if resp.ExitCode != 4 {
if existsTime.IsZero() {
existsTime = time.Now()
}
if resp.ExitCode == 0 || time.Since(existsTime) > 10*time.Second {
break
}
}
time.Sleep(800 * time.Millisecond)
}
s.cmd = exec.CommandContext(s.ctx, "journalctl",
"-f",
"-b",
"-n", "20",
"-o", "json",
"-u", s.unit,
)
stdout, err := s.cmd.StdoutPipe()
if err != nil {
err = &errortypes.ReadError{
errors.Wrap(err, "agent: Error creating stdout pipe"),
}
return
}
err = s.cmd.Start()
if err != nil {
err = &errortypes.ExecError{
errors.Wrap(err, "agent: Error starting journalctl"),
}
return
}
scanner := bufio.NewScanner(stdout)
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)
for scanner.Scan() {
select {
case <-s.ctx.Done():
return
default:
}
line := scanner.Bytes()
var entry journalEntry
e := json.Unmarshal(line, &entry)
if e != nil {
continue
}
var timestamp time.Time
ts, e := strconv.ParseInt(entry.Timestamp, 10, 64)
if e == nil {
timestamp = time.Unix(0, ts*1000)
} else {
timestamp = time.Now()
}
level := int32(5)
if entry.Priority != "" {
switch entry.Priority {
case "0":
level = 1
case "1", "2":
level = 2
case "3":
level = 3
case "4":
level = 4
case "5", "6":
level = 5
case "7":
level = 6
}
}
select {
case s.output <- &types.Entry{
Timestamp: timestamp,
Level: level,
Message: strings.TrimSuffix(entry.Message, "\n"),
}:
default:
}
}
err = scanner.Err()
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "agent: Error reading journal"),
}
return
}
s.cmd.Wait()
return
}
func (s *Systemd) Open() (err error) {
s.output = make(chan *types.Entry, 10000)
s.ctx, s.cancel = context.WithCancel(context.Background())
go func() {
defer func() {
panc := recover()
if panc != nil {
logger.WithFields(logger.Fields{
"trace": string(debug.Stack()),
"panic": panc,
}).Error("sync: Panic in journal open")
}
}()
for {
select {
case <-s.ctx.Done():
return
default:
}
e := s.followJournal()
select {
case <-s.ctx.Done():
return
default:
}
if e != nil {
logger.WithFields(logger.Fields{
"unit": s.unit,
"error": e,
}).Error("agent: Journal follower error, restarting")
} else {
logger.WithFields(logger.Fields{
"unit": s.unit,
}).Info("agent: Journal follower exited, restarting")
}
select {
case <-time.After(3 * time.Second):
case <-s.ctx.Done():
return
}
}
}()
return
}
func (s *Systemd) Close() (err error) {
defer func() {
panc := recover()
if panc != nil {
logger.WithFields(logger.Fields{
"trace": string(debug.Stack()),
"panic": panc,
}).Error("sync: Panic in journal close")
}
}()
if s.cancel != nil {
s.cancel()
}
if s.cmd != nil && s.cmd.Process != nil {
s.cmd.Process.Kill()
}
if s.output != nil {
close(s.output)
}
return
}
func NewSystemd(unit string) *Systemd {
return &Systemd{
unit: unit,
}
}
================================================
FILE: agent/utils/sanitize.go
================================================
package utils
import (
"strings"
"github.com/pritunl/pritunl-cloud/agent/constants"
"github.com/pritunl/tools/commander"
)
type fileOp struct {
cmd string
args []string
path string
}
type findOp struct {
path string
pattern string
action string
}
func Sanitize() (err error) {
operations := []fileOp{
{"rm", []string{"-f"}, "/var/lib/systemd/random-seed"},
{"rm", []string{"-f"}, "/etc/machine-id"},
{"rm", []string{"-rf"}, "/root/.cache"},
{"shred", []string{"-u"}, "/root/.ssh/authorized_keys"},
{"shred", []string{"-u"}, "/root/.bash_history"},
{"shred", []string{"-u"}, "/var/log/lastlog"},
{"shred", []string{"-u"}, "/var/log/secure"},
{"shred", []string{"-u"}, "/var/log/utmp"},
{"shred", []string{"-u"}, "/var/log/wtmp"},
{"shred", []string{"-u"}, "/var/log/btmp"},
{"shred", []string{"-u"}, "/var/log/dmesg"},
{"shred", []string{"-u"}, "/var/log/dmesg.old"},
{"shred", []string{"-u"}, "/var/lib/systemd/random-seed"},
}
findOps := []findOp{
{"/var/tmp", "-name dnf-*", "rm -rf"},
{"/home", "-type d -name .cache", "rm -rf"},
{"/home", "-type f -name .bash_history", "rm -f"},
{"/var/log", "-type f -name *.gz", "rm -f"},
{"/var/log", "-type f -name *.[0-9]", "rm -f"},
{"/var/log", "-type f -name *-????????", "rm -f"},
{"/var/lib/cloud/instances", "-mindepth 1", "rm -rf"},
{"/etc/ssh", "-type f -name *_key", "shred -u"},
{"/etc/ssh", "-type f -name *_key.pub", "shred -u"},
{"/var/log", "-mtime -1 -type f", "truncate -s 0"},
}
_, _ = commander.Exec(&commander.Opt{
Name: "sync",
Args: []string{},
PipeOut: true,
PipeErr: true,
})
for _, op := range operations {
_, _ = commander.Exec(&commander.Opt{
Name: op.cmd,
Args: append(op.args, op.path),
PipeOut: true,
PipeErr: true,
})
}
for _, op := range findOps {
args := []string{op.path}
if op.pattern != "" {
args = append(args, strings.Split(op.pattern, " ")...)
}
args = append(args, "-exec")
args = append(args, strings.Split(op.action, " ")...)
args = append(args, "{}", ";")
_, _ = commander.Exec(&commander.Opt{
Name: "find",
Args: args,
PipeOut: true,
PipeErr: true,
})
}
_, _ = commander.Exec(&commander.Opt{
Name: "touch",
Args: []string{"/etc/machine-id"},
PipeOut: true,
PipeErr: true,
})
_, _ = commander.Exec(&commander.Opt{
Name: "sync",
Args: []string{},
PipeOut: true,
PipeErr: true,
})
_, _ = commander.Exec(&commander.Opt{
Name: "history",
Args: []string{"-c"},
PipeOut: true,
PipeErr: true,
})
_, _ = commander.Exec(&commander.Opt{
Name: "fstrim",
Args: []string{"-av"},
PipeOut: true,
PipeErr: true,
})
return
}
func SanitizeImds() (err error) {
_, _ = commander.Exec(&commander.Opt{
Name: "shred",
Args: []string{"-u", constants.ImdsLogPath},
PipeOut: true,
PipeErr: true,
})
_, _ = commander.Exec(&commander.Opt{
Name: "shred",
Args: []string{"-u", constants.ImdsConfPath},
PipeOut: true,
PipeErr: true,
})
return
}
================================================
FILE: agent/utils/sys.go
================================================
package utils
import (
"io/ioutil"
"os"
"time"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/errortypes"
)
func Read(path string) (data string, err error) {
dataByt, err := ioutil.ReadFile(path)
if err != nil {
err = &errortypes.ReadError{
errors.Wrapf(err, "utils: Failed to read '%s'", path),
}
return
}
data = string(dataByt)
return
}
func DelayExit(code int, delay time.Duration) {
time.Sleep(delay)
os.Exit(code)
}
================================================
FILE: aggregate/block.go
================================================
package aggregate
import (
"sync"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/mongo-go-driver/v2/mongo"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/pritunl-cloud/block"
"github.com/pritunl/pritunl-cloud/database"
)
type BlockPipe struct {
block.Block `bson:",inline"`
IpCount int64 `bson:"ip_count"`
}
type BlocksPipe struct {
Metadata []*Metadata `bson:"meta"`
Blocks []*BlockPipe `bson:"blocks"`
}
type BlockAggregate struct {
block.Block
Available int64 `json:"available"`
Capacity int64 `json:"capacity"`
}
func GetBlockPaged(db *database.Database, query *bson.M, page,
pageCount int64) (blocks []*BlockAggregate, count int64, err error) {
coll := db.Blocks()
blocks = []*BlockAggregate{}
if pageCount == 0 {
pageCount = 20
}
skip := page * pageCount
addBlock := func(doc *BlockPipe) error {
total, e := doc.GetIpCount()
if e != nil {
return e
}
blck := &BlockAggregate{
Block: doc.Block,
Available: total - doc.IpCount,
Capacity: total,
}
blocks = append(blocks, blck)
return nil
}
var cursor *mongo.Cursor
if len(*query) == 0 {
waiter := &sync.WaitGroup{}
var countErr error
waiter.Add(1)
go func() {
defer waiter.Done()
count, countErr = coll.EstimatedDocumentCount(db)
if countErr != nil {
countErr = database.ParseError(countErr)
return
}
}()
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "blocks_ip",
"localField": "_id",
"foreignField": "block",
"as": "ips",
},
},
&bson.M{
"$addFields": &bson.M{
"ip_count": &bson.M{
"$size": "$ips",
},
},
},
&bson.M{
"$project": &bson.M{
"ips": 0,
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
for cursor.Next(db) {
doc := &BlockPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
err = addBlock(doc)
if err != nil {
return
}
}
waiter.Wait()
if countErr != nil {
err = countErr
return
}
} else {
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$facet": &bson.M{
"meta": []*bson.M{
&bson.M{
"$count": "count",
},
},
"blocks": []*bson.M{
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "blocks_ip",
"localField": "_id",
"foreignField": "block",
"as": "ips",
},
},
&bson.M{
"$addFields": &bson.M{
"ip_count": &bson.M{
"$size": "$ips",
},
},
},
&bson.M{
"$project": &bson.M{
"ips": 0,
},
},
},
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
if !cursor.Next(db) {
err = &database.NotFoundError{
errors.New("aggregate: Not found"),
}
return
}
doc := &BlocksPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
if len(doc.Metadata) > 0 {
count = doc.Metadata[0].Count
}
for _, blockDoc := range doc.Blocks {
err = addBlock(blockDoc)
if err != nil {
return
}
}
}
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: aggregate/deployment.go
================================================
package aggregate
import (
"time"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/deployment"
"github.com/pritunl/pritunl-cloud/image"
"github.com/pritunl/pritunl-cloud/imds/types"
"github.com/pritunl/pritunl-cloud/instance"
"github.com/pritunl/pritunl-cloud/journal"
"github.com/pritunl/pritunl-cloud/node"
"github.com/pritunl/pritunl-cloud/spec"
"github.com/pritunl/pritunl-cloud/unit"
"github.com/pritunl/pritunl-cloud/zone"
)
type DeploymentPipe struct {
Deployment `bson:",inline"`
SpecDocs []*spec.Spec `bson:"spec_docs"`
InstanceDocs []*instance.Instance `bson:"instance_docs"`
ZoneDocs []*zone.Zone `bson:"zone_docs"`
NodeDocs []*node.Node `bson:"node_docs"`
ImageDocs []*image.Image `bson:"image_docs"`
}
type Deployment struct {
Id bson.ObjectID `bson:"_id" json:"id"`
Pod bson.ObjectID `bson:"pod" json:"pod"`
Unit bson.ObjectID `bson:"unit" json:"unit"`
Spec bson.ObjectID `bson:"spec" json:"spec"`
SpecOffset int `bson:"spec_offset" json:"spec_offset"`
SpecIndex int `bson:"spec_index" json:"spec_index"`
SpecTimestamp time.Time `bson:"spec_timestamp" json:"spec_timestamp"`
Timestamp time.Time `bson:"timestamp" json:"timestamp"`
Tags []string `bson:"tags" json:"tags"`
Kind string `bson:"kind" json:"kind"`
State string `bson:"state" json:"state"`
Action string `bson:"action" json:"action"`
Status string `bson:"status" json:"status"`
Node bson.ObjectID `bson:"node" json:"node"`
Instance bson.ObjectID `bson:"instance" json:"instance"`
InstanceData *deployment.InstanceData `bson:"instance_data" json:"instance_data"`
DomainData *deployment.DomainData `bson:"domain_data" json:"domain_data"`
Journals []*deployment.Journal `bson:"journals" json:"journals"`
ImageId bson.ObjectID `bson:"image_id" json:"image_id"`
ImageName string `bson:"image_name" json:"image_name"`
ZoneName string `bson:"-" json:"zone_name"`
NodeName string `bson:"-" json:"node_name"`
InstanceName string `bson:"-" json:"instance_name"`
InstanceRoles []string `bson:"-" json:"instance_roles"`
InstanceMemory int `bson:"-" json:"instance_memory"`
InstanceProcessors int `bson:"-" json:"instance_processors"`
InstanceStatus string `bson:"-" json:"instance_status"`
InstanceUptime string `bson:"-" json:"instance_uptime"`
InstanceState string `bson:"-" json:"instance_state"`
InstanceAction string `bson:"-" json:"instance_action"`
InstanceGuestStatus string `bson:"-" json:"instance_guest_status"`
InstanceTimestamp time.Time `bson:"-" json:"instance_timestamp"`
InstanceHeartbeat time.Time `bson:"-" json:"instance_heartbeat"`
InstanceMemoryUsage float64 `bson:"-" json:"instance_memory_usage"`
InstanceHugePages float64 `bson:"-" json:"instance_hugepages"`
InstanceLoad1 float64 `bson:"-" json:"instance_load1"`
InstanceLoad5 float64 `bson:"-" json:"instance_load5"`
InstanceLoad15 float64 `bson:"-" json:"instance_load15"`
}
func GetDeployments(db *database.Database, unt *unit.Unit) (
deplys []*Deployment, err error) {
coll := db.Deployments()
deplys = []*Deployment{}
cursor, err := coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": &bson.M{
"unit": unt.Id,
},
},
&bson.M{
"$sort": &bson.M{
"timestamp": -1,
},
},
&bson.M{
"$lookup": &bson.M{
"from": "specs",
"localField": "spec",
"foreignField": "_id",
"as": "spec_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "instances",
"localField": "instance",
"foreignField": "_id",
"as": "instance_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "zones",
"localField": "zone",
"foreignField": "_id",
"as": "zone_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "nodes",
"localField": "node",
"foreignField": "_id",
"as": "node_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "images",
"localField": "_id",
"foreignField": "deployment",
"as": "image_docs",
},
},
&bson.M{
"$project": &bson.D{
{"_id", 1},
{"pod", 1},
{"unit", 1},
{"timestamp", 1},
{"tags", 1},
{"spec", 1},
{"kind", 1},
{"state", 1},
{"action", 1},
{"status", 1},
{"node", 1},
{"instance", 1},
{"instance_data", 1},
{"domain_data", 1},
{"journals", 1},
{"spec_docs.index", 1},
{"spec_docs.timestamp", 1},
{"instance_docs.name", 1},
{"instance_docs.roles", 1},
{"instance_docs.memory", 1},
{"instance_docs.processors", 1},
{"instance_docs.state", 1},
{"instance_docs.action", 1},
{"instance_docs.timestamp", 1},
{"instance_docs.restart", 1},
{"instance_docs.restart_block_ip", 1},
{"instance_docs.guest", 1},
{"zone_docs.name", 1},
{"node_docs.name", 1},
{"image_docs._id", 1},
{"image_docs.name", 1},
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
latest := true
for cursor.Next(db) {
doc := &DeploymentPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
deply := &doc.Deployment
if deply.Tags == nil {
deply.Tags = []string{}
}
if latest {
latest = false
if doc.Kind == deployment.Image {
deply.Tags = append([]string{"latest"}, deply.Tags...)
}
}
deply.Journals = append([]*deployment.Journal{
{
Index: journal.DeploymentAgent,
Key: "agent",
Type: "agent",
},
}, deply.Journals...)
if len(doc.ZoneDocs) > 0 {
zne := doc.ZoneDocs[0]
deply.ZoneName = zne.Name
}
if len(doc.NodeDocs) > 0 {
nde := doc.NodeDocs[0]
deply.NodeName = nde.Name
}
if len(doc.SpecDocs) > 0 {
spc := doc.SpecDocs[0]
deply.SpecOffset = spc.Index - unt.SpecIndex
deply.SpecIndex = spc.Index
deply.SpecTimestamp = spc.Timestamp
}
if len(doc.InstanceDocs) > 0 {
inst := doc.InstanceDocs[0]
inst.Json(true)
deply.InstanceName = inst.Name
deply.InstanceRoles = inst.Roles
deply.InstanceMemory = inst.Memory
deply.InstanceProcessors = inst.Processors
deply.InstanceStatus = inst.Status
deply.InstanceUptime = inst.Uptime
deply.InstanceState = inst.State
deply.InstanceAction = inst.Action
if inst.Guest != nil {
deply.InstanceGuestStatus = inst.Guest.Status
deply.InstanceTimestamp = inst.Guest.Timestamp
deply.InstanceHeartbeat = inst.Guest.Heartbeat
if inst.IsActive() {
deply.InstanceMemoryUsage = inst.Guest.Memory
deply.InstanceHugePages = inst.Guest.HugePages
deply.InstanceLoad1 = inst.Guest.Load1
deply.InstanceLoad5 = inst.Guest.Load5
deply.InstanceLoad15 = inst.Guest.Load15
} else {
deply.InstanceGuestStatus = types.Offline
}
}
}
if len(doc.ImageDocs) > 0 {
img := doc.ImageDocs[0]
deply.ImageId = img.Id
deply.ImageName = img.Name
}
deplys = append(deplys, deply)
}
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: aggregate/disk.go
================================================
package aggregate
import (
"sync"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/mongo-go-driver/v2/mongo"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/disk"
"github.com/pritunl/pritunl-cloud/node"
)
type DiskPipe struct {
disk.Disk `bson:",inline"`
ImageDocs []*node.Node `bson:"image_docs"`
}
type DisksPipe struct {
Metadata []*Metadata `bson:"meta"`
Disks []*DiskPipe `bson:"disks"`
}
type DiskBackup struct {
Image bson.ObjectID `json:"image"`
Name string `json:"name"`
}
type DiskAggregate struct {
disk.Disk
Backups []*DiskBackup `json:"backups"`
}
func GetDiskPaged(db *database.Database, query *bson.M, page,
pageCount int64) (disks []*DiskAggregate, count int64, err error) {
coll := db.Disks()
disks = []*DiskAggregate{}
if pageCount == 0 {
pageCount = 20
}
skip := page * pageCount
addDisk := func(doc *DiskPipe) {
backups := []*DiskBackup{}
for _, img := range doc.ImageDocs {
backup := &DiskBackup{
Image: img.Id,
Name: img.Name,
}
backups = append(backups, backup)
}
dsk := &DiskAggregate{
Disk: doc.Disk,
Backups: backups,
}
disks = append(disks, dsk)
}
var cursor *mongo.Cursor
if len(*query) == 0 {
waiter := &sync.WaitGroup{}
var countErr error
waiter.Add(1)
go func() {
defer waiter.Done()
count, countErr = coll.EstimatedDocumentCount(db)
if countErr != nil {
countErr = database.ParseError(countErr)
return
}
}()
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "images",
"localField": "_id",
"foreignField": "disk",
"as": "image_docs",
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
for cursor.Next(db) {
doc := &DiskPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
addDisk(doc)
}
waiter.Wait()
if countErr != nil {
err = countErr
return
}
} else {
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$facet": &bson.M{
"meta": []*bson.M{
&bson.M{
"$count": "count",
},
},
"disks": []*bson.M{
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "images",
"localField": "_id",
"foreignField": "disk",
"as": "image_docs",
},
},
},
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
if !cursor.Next(db) {
err = &database.NotFoundError{
errors.New("aggregate: Not found"),
}
return
}
doc := &DisksPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
if len(doc.Metadata) > 0 {
count = doc.Metadata[0].Count
}
for _, diskDoc := range doc.Disks {
addDisk(diskDoc)
}
}
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: aggregate/domain.go
================================================
package aggregate
import (
"sync"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/mongo-go-driver/v2/mongo"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/domain"
)
type Domain struct {
domain.Domain `bson:",inline"`
Records []*domain.Record `bson:"records" json:"records"`
}
type DomainsPipe struct {
Metadata []*Metadata `bson:"meta"`
Domains []*Domain `bson:"domains"`
}
func GetDomainPaged(db *database.Database, query *bson.M, page,
pageCount int64) (domains []*domain.Domain, count int64, err error) {
coll := db.Domains()
domains = []*domain.Domain{}
if pageCount == 0 {
pageCount = 20
}
skip := page * pageCount
addDomain := func(domn *Domain) {
domn.Domain.Records = domn.Records
domn.Json()
domains = append(domains, &domn.Domain)
}
var cursor *mongo.Cursor
if len(*query) == 0 {
waiter := &sync.WaitGroup{}
var countErr error
waiter.Add(1)
go func() {
defer waiter.Done()
count, countErr = coll.EstimatedDocumentCount(db)
if countErr != nil {
countErr = database.ParseError(countErr)
return
}
}()
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "domains_records",
"localField": "_id",
"foreignField": "domain",
"as": "records",
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
for cursor.Next(db) {
domn := &Domain{}
err = cursor.Decode(domn)
if err != nil {
err = database.ParseError(err)
return
}
addDomain(domn)
}
waiter.Wait()
if countErr != nil {
err = countErr
return
}
} else {
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$facet": &bson.M{
"meta": []*bson.M{
&bson.M{
"$count": "count",
},
},
"domains": []*bson.M{
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "domains_records",
"localField": "_id",
"foreignField": "domain",
"as": "records",
},
},
},
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
if !cursor.Next(db) {
err = &database.NotFoundError{
errors.New("aggregate: Not found"),
}
return
}
doc := &DomainsPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
if len(doc.Metadata) > 0 {
count = doc.Metadata[0].Count
}
for _, domn := range doc.Domains {
addDomain(domn)
}
}
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: aggregate/instance.go
================================================
package aggregate
import (
"fmt"
"sort"
"strings"
"sync"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/mongo-go-driver/v2/mongo"
"github.com/pritunl/pritunl-cloud/authority"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/datacenter"
"github.com/pritunl/pritunl-cloud/disk"
"github.com/pritunl/pritunl-cloud/drive"
"github.com/pritunl/pritunl-cloud/firewall"
"github.com/pritunl/pritunl-cloud/instance"
"github.com/pritunl/pritunl-cloud/iso"
"github.com/pritunl/pritunl-cloud/node"
"github.com/pritunl/pritunl-cloud/pci"
"github.com/pritunl/pritunl-cloud/usb"
"github.com/pritunl/pritunl-cloud/vm"
)
type InstancePipe struct {
instance.Instance `bson:",inline"`
NodeDocs []*node.Node `bson:"node_docs"`
DatacenterDocs []*datacenter.Datacenter `bson:"datacenter_docs"`
DiskDocs []*disk.Disk `bson:"disk_docs"`
}
type InstancesPipe struct {
Metadata []*Metadata `bson:"meta"`
Instances []*InstancePipe `bson:"instances"`
}
type InstanceInfo struct {
Node string `json:"node"`
NodePublicIp string `json:"node_public_ip"`
Mtu int `json:"mtu"`
Iscsi bool `json:"iscsi"`
Disks []string `json:"disks"`
FirewallRules map[string]string `json:"firewall_rules"`
Authorities []string `json:"authorities"`
Isos []*iso.Iso `json:"isos"`
UsbDevices []*usb.Device `json:"usb_devices"`
PciDevices []*pci.Device `json:"pci_devices"`
DriveDevices []*drive.Device `json:"drive_devices"`
CloudSubnets []*node.CloudSubnet `json:"cloud_subnets"`
}
type InstanceAggregate struct {
instance.Instance
Info *InstanceInfo `json:"info"`
}
func GetInstancePaged(db *database.Database, query *bson.M, page,
pageCount int64) (insts []*InstanceAggregate, count int64, err error) {
coll := db.Instances()
insts = []*InstanceAggregate{}
if pageCount == 0 {
pageCount = 20
}
skip := page * pageCount
firesOrg := map[bson.ObjectID]map[string][]*firewall.Firewall{}
firesRoles := map[bson.ObjectID]set.Set{}
authrsOrg := map[bson.ObjectID]map[string][]*authority.Authority{}
authrsRoles := map[bson.ObjectID]set.Set{}
addInstance := func(doc *InstancePipe) error {
info := &InstanceInfo{
Node: "Unknown",
Disks: []string{},
FirewallRules: map[string]string{},
Authorities: []string{},
CloudSubnets: []*node.CloudSubnet{},
}
var nde *node.Node
var dc *datacenter.Datacenter
if len(doc.NodeDocs) > 0 {
nde = doc.NodeDocs[0]
}
if len(doc.DatacenterDocs) > 0 {
dc = doc.DatacenterDocs[0]
}
if nde != nil {
info.Node = nde.Name
if len(nde.PublicIps) > 0 {
info.NodePublicIp = nde.PublicIps[0]
}
info.Iscsi = nde.Iscsi
info.Isos = nde.LocalIsos
info.CloudSubnets = nde.GetCloudSubnetsName()
if nde.UsbPassthrough {
info.UsbDevices = nde.UsbDevices
}
if nde.PciDevices != nil {
info.PciDevices = nde.PciDevices
}
if nde.InstanceDrives != nil {
info.DriveDevices = nde.InstanceDrives
}
}
if nde != nil && dc != nil {
info.Mtu = dc.GetInstanceMtu()
}
for _, dsk := range doc.DiskDocs {
info.Disks = append(
info.Disks,
fmt.Sprintf("%s: %s", dsk.Index, dsk.Name),
)
}
fires := firesOrg[doc.Organization]
if fires == nil {
var e error
fires, e = firewall.GetOrgMapRoles(db, doc.Organization)
if e != nil {
return e
}
for _, roleFires := range fires {
for _, fire := range roleFires {
if _, ok := firesRoles[fire.Id]; ok {
continue
}
roles := set.NewSet()
for _, role := range fire.Roles {
roles.Add(role)
}
firesRoles[fire.Id] = roles
}
}
firesOrg[doc.Organization] = fires
}
authrs := authrsOrg[doc.Organization]
if authrs == nil {
var e error
authrs, e = authority.GetOrgMapRoles(db, doc.Organization)
if e != nil {
return e
}
for _, roleAuthrs := range authrs {
for _, authr := range roleAuthrs {
if _, ok := authrsRoles[authr.Id]; ok {
continue
}
roles := set.NewSet()
for _, role := range authr.Roles {
roles.Add(role)
}
authrsRoles[authr.Id] = roles
}
}
authrsOrg[doc.Organization] = authrs
}
curFires := set.NewSet()
firewallRules := map[string]set.Set{}
firewallRulesKeys := []string{}
authrNames := set.NewSet()
for _, role := range doc.Roles {
roleFires := fires[role]
for _, fire := range roleFires {
if curFires.Contains(fire.Id) {
continue
}
curFires.Add(fire.Id)
for _, rule := range fire.Ingress {
key := rule.Protocol
if rule.Port != "" {
key += ":" + rule.Port
}
rules := firewallRules[key]
if rules == nil {
rules = set.NewSet()
firewallRules[key] = rules
firewallRulesKeys = append(
firewallRulesKeys,
key,
)
}
for _, sourceIp := range rule.SourceIps {
rules.Add(sourceIp)
}
}
}
roleAuthrs := authrs[role]
for _, authr := range roleAuthrs {
authrNames.Add(authr.Name)
}
}
if !doc.Instance.Deployment.IsZero() {
doc.Instance.LoadVirt(nil, nil)
specRules, _, e := firewall.GetSpecRulesSlow(
db, doc.Instance.Node, []*instance.Instance{&doc.Instance})
if e != nil {
return e
}
instNamespace := vm.GetNamespace(doc.Instance.Id, 0)
for namespace, rules := range specRules {
if namespace != instNamespace {
continue
}
for _, rule := range rules {
key := rule.Protocol
if rule.Port != "" {
key += ":" + rule.Port
}
rules := firewallRules[key]
if rules == nil {
rules = set.NewSet()
firewallRules[key] = rules
firewallRulesKeys = append(
firewallRulesKeys,
key,
)
}
for _, sourceIp := range rule.SourceIps {
rules.Add(sourceIp)
}
}
}
}
sort.Strings(firewallRulesKeys)
for _, key := range firewallRulesKeys {
rules := firewallRules[key]
vals := []string{}
for rule := range rules.Iter() {
vals = append(vals, rule.(string))
}
sort.Strings(vals)
info.FirewallRules[key] = strings.Join(vals, ", ")
}
for authr := range authrNames.Iter() {
info.Authorities = append(info.Authorities, authr.(string))
}
sort.Strings(info.Authorities)
inst := &InstanceAggregate{
Instance: doc.Instance,
Info: info,
}
insts = append(insts, inst)
return nil
}
var cursor *mongo.Cursor
if len(*query) == 0 {
waiter := &sync.WaitGroup{}
var countErr error
waiter.Add(1)
go func() {
defer waiter.Done()
count, countErr = coll.EstimatedDocumentCount(db)
if countErr != nil {
countErr = database.ParseError(countErr)
return
}
}()
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "nodes",
"localField": "node",
"foreignField": "_id",
"as": "node_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "datacenters",
"localField": "datacenter",
"foreignField": "_id",
"as": "datacenter_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "disks",
"localField": "_id",
"foreignField": "instance",
"as": "disk_docs",
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
for cursor.Next(db) {
doc := &InstancePipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
err = addInstance(doc)
if err != nil {
return
}
}
waiter.Wait()
if countErr != nil {
err = countErr
return
}
} else {
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$facet": &bson.M{
"meta": []*bson.M{
&bson.M{
"$count": "count",
},
},
"instances": []*bson.M{
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "nodes",
"localField": "node",
"foreignField": "_id",
"as": "node_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "datacenters",
"localField": "datacenter",
"foreignField": "_id",
"as": "datacenter_docs",
},
},
&bson.M{
"$lookup": &bson.M{
"from": "disks",
"localField": "_id",
"foreignField": "instance",
"as": "disk_docs",
},
},
},
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
if !cursor.Next(db) {
err = &database.NotFoundError{
errors.New("aggregate: Not found"),
}
return
}
doc := &InstancesPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
if len(doc.Metadata) > 0 {
count = doc.Metadata[0].Count
}
for _, instDoc := range doc.Instances {
err = addInstance(instDoc)
if err != nil {
return
}
}
}
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: aggregate/pod.go
================================================
package aggregate
import (
"sort"
"sync"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/mongo-go-driver/v2/mongo"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/pod"
"github.com/pritunl/pritunl-cloud/unit"
)
func sortUnits(units []*unit.Unit) {
sort.SliceStable(units, func(i, j int) bool {
return units[i].Name < units[j].Name
})
}
type PodPipe struct {
pod.Pod `bson:",inline"`
UnitDocs []*unit.Unit `bson:"unit_docs"`
}
type Metadata struct {
Count int64 `bson:"count"`
}
type PodsPipe struct {
Metadata []*Metadata `bson:"meta"`
Pods []*PodPipe `bson:"pods"`
}
type PodAggregate struct {
pod.Pod
Units []*unit.Unit `json:"units"`
}
func GetPod(db *database.Database, usrId bson.ObjectID, query *bson.M) (
pd *PodAggregate, err error) {
coll := db.Pods()
cursor, err := coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$lookup": &bson.M{
"from": "units",
"localField": "_id",
"foreignField": "pod",
"as": "unit_docs",
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
if !cursor.Next(db) {
err = &database.NotFoundError{
errors.New("aggregate: Pod not found"),
}
return
}
doc := &PodPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
sortUnits(doc.UnitDocs)
pd = &PodAggregate{
Pod: doc.Pod,
Units: doc.UnitDocs,
}
pd.Json(usrId)
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
func GetPodsPaged(db *database.Database, usrId bson.ObjectID,
query *bson.M, page, pageCount int64) (pods []*PodAggregate,
count int64, err error) {
coll := db.Pods()
pods = []*PodAggregate{}
if pageCount == 0 {
pageCount = 20
}
skip := page * pageCount
var cursor *mongo.Cursor
if len(*query) == 0 {
waiter := &sync.WaitGroup{}
var countErr error
waiter.Add(1)
go func() {
defer waiter.Done()
count, countErr = coll.EstimatedDocumentCount(db)
if countErr != nil {
countErr = database.ParseError(countErr)
return
}
}()
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "units",
"localField": "_id",
"foreignField": "pod",
"as": "unit_docs",
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
for cursor.Next(db) {
doc := &PodPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
sortUnits(doc.UnitDocs)
pd := &PodAggregate{
Pod: doc.Pod,
Units: doc.UnitDocs,
}
pd.Json(usrId)
pods = append(pods, pd)
}
waiter.Wait()
if countErr != nil {
err = countErr
return
}
} else {
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$facet": &bson.M{
"meta": []*bson.M{
&bson.M{
"$count": "count",
},
},
"pods": []*bson.M{
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
&bson.M{
"$lookup": &bson.M{
"from": "units",
"localField": "_id",
"foreignField": "pod",
"as": "unit_docs",
},
},
},
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
if !cursor.Next(db) {
err = &database.NotFoundError{
errors.New("aggregate: Not found"),
}
return
}
doc := &PodsPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
if len(doc.Metadata) > 0 {
count = doc.Metadata[0].Count
}
for _, podDoc := range doc.Pods {
sortUnits(podDoc.UnitDocs)
pd := &PodAggregate{
Pod: podDoc.Pod,
Units: podDoc.UnitDocs,
}
pd.Json(usrId)
pods = append(pods, pd)
}
}
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: aggregate/shape.go
================================================
package aggregate
import (
"sync"
"github.com/dropbox/godropbox/errors"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/mongo-go-driver/v2/mongo"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/node"
"github.com/pritunl/pritunl-cloud/shape"
)
type ShapePipe struct {
shape.Shape `bson:",inline"`
NodeDocs []*node.Node `bson:"node_docs"`
}
type ShapesPipe struct {
Metadata []*Metadata `bson:"meta"`
Shapes []*ShapePipe `bson:"shapes"`
}
func GetShapePaged(db *database.Database, query *bson.M, page,
pageCount int64) (shapes []*shape.Shape, count int64, err error) {
coll := db.Shapes()
shapes = []*shape.Shape{}
if pageCount == 0 {
pageCount = 20
}
skip := page * pageCount
sizeQuery := &bson.M{
"$ifNull": bson.A{
&bson.M{
"$setIntersection": bson.A{
&bson.M{"$ifNull": bson.A{"$roles", bson.A{}}},
&bson.M{"$ifNull": bson.A{"$$shape_roles", bson.A{}}},
},
},
bson.A{},
},
}
nodeLookup := &bson.M{
"$lookup": &bson.M{
"from": "nodes",
"let": &bson.M{
"shape_roles": "$roles",
},
"pipeline": []*bson.M{
{
"$match": &bson.M{
"$expr": &bson.M{
"$gt": bson.A{
&bson.M{
"$size": sizeQuery,
},
0,
},
},
},
},
},
"as": "node_docs",
},
}
addShape := func(doc *ShapePipe) {
shpe := &doc.Shape
shpe.NodeCount = len(doc.NodeDocs)
shapes = append(shapes, shpe)
}
var cursor *mongo.Cursor
if len(*query) == 0 {
waiter := &sync.WaitGroup{}
var countErr error
waiter.Add(1)
go func() {
defer waiter.Done()
count, countErr = coll.EstimatedDocumentCount(db)
if countErr != nil {
countErr = database.ParseError(countErr)
return
}
}()
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
nodeLookup,
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
for cursor.Next(db) {
doc := &ShapePipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
addShape(doc)
}
waiter.Wait()
if countErr != nil {
err = countErr
return
}
} else {
cursor, err = coll.Aggregate(db, []*bson.M{
&bson.M{
"$match": query,
},
&bson.M{
"$sort": &bson.M{
"name": 1,
},
},
&bson.M{
"$facet": &bson.M{
"meta": []*bson.M{
&bson.M{
"$count": "count",
},
},
"shapes": []*bson.M{
&bson.M{
"$skip": skip,
},
&bson.M{
"$limit": pageCount,
},
nodeLookup,
},
},
},
})
if err != nil {
err = database.ParseError(err)
return
}
defer cursor.Close(db)
if !cursor.Next(db) {
err = &database.NotFoundError{
errors.New("aggregate: Not found"),
}
return
}
doc := &ShapesPipe{}
err = cursor.Decode(doc)
if err != nil {
err = database.ParseError(err)
return
}
if len(doc.Metadata) > 0 {
count = doc.Metadata[0].Count
}
for _, shapeDoc := range doc.Shapes {
addShape(shapeDoc)
}
}
err = cursor.Err()
if err != nil {
err = database.ParseError(err)
return
}
return
}
================================================
FILE: ahandlers/alert.go
================================================
package ahandlers
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/alert"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/utils"
)
type alertData struct {
Id bson.ObjectID `json:"id"`
Name string `json:"name"`
Comment string `json:"comment"`
Organization bson.ObjectID `json:"organization"`
Roles []string `json:"roles"`
Resource string `json:"resource"`
Level int `json:"level"`
Frequency int `json:"frequency"`
Ignores []string `json:"ignores"`
ValueInt int `json:"value_int"`
ValueStr string `json:"value_str"`
}
type alertsData struct {
Alerts []*alert.Alert `json:"alerts"`
Count int64 `json:"count"`
}
func alertPut(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &alertData{}
alertId, ok := utils.ParseObjectId(c.Param("alert_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
alrt, err := alert.Get(db, alertId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
alrt.Name = data.Name
alrt.Comment = data.Comment
alrt.Organization = data.Organization
alrt.Roles = data.Roles
alrt.Resource = data.Resource
alrt.Level = data.Level
alrt.Frequency = data.Frequency
alrt.Ignores = data.Ignores
alrt.ValueInt = data.ValueInt
alrt.ValueStr = data.ValueStr
fields := set.NewSet(
"name",
"comment",
"organization",
"roles",
"resource",
"level",
"frequency",
"ignores",
"value_int",
"value_str",
)
errData, err := alrt.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = alrt.CommitFields(db, fields)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
_ = event.PublishDispatch(db, "alert.change")
c.JSON(200, alrt)
}
func alertPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &alertData{
Name: "new-alert",
Resource: alert.InstanceOffline,
Level: alert.Medium,
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
alrt := &alert.Alert{
Name: data.Name,
Comment: data.Comment,
Organization: data.Organization,
Roles: data.Roles,
Resource: data.Resource,
Level: data.Level,
Frequency: data.Frequency,
Ignores: data.Ignores,
ValueInt: data.ValueInt,
ValueStr: data.ValueStr,
}
errData, err := alrt.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = alrt.Insert(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
_ = event.PublishDispatch(db, "alert.change")
c.JSON(200, alrt)
}
func alertDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
alertId, ok := utils.ParseObjectId(c.Param("alert_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := alert.Remove(db, alertId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
_ = event.PublishDispatch(db, "alert.change")
c.JSON(200, nil)
}
func alertsDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
dta := []bson.ObjectID{}
err := c.Bind(&dta)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
err = alert.RemoveMulti(db, dta)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
_ = event.PublishDispatch(db, "alert.change")
c.JSON(200, nil)
}
func alertGet(c *gin.Context) {
if demo.IsDemo() {
alrt := demo.Alerts[0]
c.JSON(200, alrt)
return
}
db := c.MustGet("db").(*database.Database)
alertId, ok := utils.ParseObjectId(c.Query("id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
alrt, err := alert.Get(db, alertId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, alrt)
}
func alertsGet(c *gin.Context) {
if demo.IsDemo() {
data := &alertsData{
Alerts: demo.Alerts,
Count: int64(len(demo.Alerts)),
}
c.JSON(200, data)
return
}
db := c.MustGet("db").(*database.Database)
page, _ := strconv.ParseInt(c.Query("page"), 10, 0)
pageCount, _ := strconv.ParseInt(c.Query("page_count"), 10, 0)
query := bson.M{}
alertId, ok := utils.ParseObjectId(c.Query("id"))
if ok {
query["_id"] = alertId
}
name := strings.TrimSpace(c.Query("name"))
if name != "" {
query["$or"] = []*bson.M{
&bson.M{
"name": &bson.M{
"$regex": fmt.Sprintf(".*%s.*", regexp.QuoteMeta(name)),
"$options": "i",
},
},
}
}
role := strings.TrimSpace(c.Query("role"))
if role != "" {
if strings.HasPrefix(role, "~") {
role := role[1:]
if strings.HasPrefix(role, "!") {
query["roles"] = &bson.M{
"$not": &bson.M{
"$regex": fmt.Sprintf(".*%s.*",
regexp.QuoteMeta(role[1:])),
"$options": "i",
},
}
} else {
query["$or"] = []*bson.M{
&bson.M{
"roles": &bson.M{
"$regex": fmt.Sprintf(".*%s.*",
regexp.QuoteMeta(role)),
"$options": "i",
},
},
}
}
} else {
if strings.HasPrefix(role, "!") {
role = strings.TrimLeft(role, "!")
query["roles"] = &bson.M{
"$ne": role,
}
} else {
query["roles"] = role
}
}
}
organization, ok := utils.ParseObjectId(c.Query("organization"))
if ok {
query["organization"] = organization
}
comment := strings.TrimSpace(c.Query("comment"))
if comment != "" {
query["comment"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", comment),
"$options": "i",
}
}
alerts, count, err := alert.GetAllPaged(
db, &query, page, pageCount)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
dta := &alertsData{
Alerts: alerts,
Count: count,
}
c.JSON(200, dta)
}
================================================
FILE: ahandlers/audit.go
================================================
package ahandlers
import (
"strconv"
"github.com/gin-gonic/gin"
"github.com/pritunl/pritunl-cloud/audit"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/utils"
)
type auditsData struct {
Audits []*audit.Audit `json:"audits"`
Count int64 `json:"count"`
}
func auditsGet(c *gin.Context) {
if demo.IsDemo() {
data := &auditsData{
Audits: demo.Audits,
Count: int64(len(demo.Audits)),
}
c.JSON(200, data)
return
}
db := c.MustGet("db").(*database.Database)
page, _ := strconv.ParseInt(c.Query("page"), 10, 0)
pageCount, _ := strconv.ParseInt(c.Query("page_count"), 10, 0)
userId, ok := utils.ParseObjectId(c.Param("user_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
audits, count, err := audit.GetAll(db, userId, page, pageCount)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data := &auditsData{
Audits: audits,
Count: count,
}
c.JSON(200, data)
}
================================================
FILE: ahandlers/auth.go
================================================
package ahandlers
import (
"strings"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/audit"
"github.com/pritunl/pritunl-cloud/auth"
"github.com/pritunl/pritunl-cloud/authorizer"
"github.com/pritunl/pritunl-cloud/cookie"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/device"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/node"
"github.com/pritunl/pritunl-cloud/secondary"
"github.com/pritunl/pritunl-cloud/session"
"github.com/pritunl/pritunl-cloud/utils"
"github.com/pritunl/pritunl-cloud/validator"
)
func authStateGet(c *gin.Context) {
data := auth.GetState()
if demo.IsDemo() {
provider := &auth.StateProvider{
Id: "demo",
Type: "demo",
Label: "demo",
}
data.Providers = append(data.Providers, provider)
}
c.JSON(200, data)
}
type authData struct {
Username string `json:"username"`
Password string `json:"password"`
}
func authSessionPost(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
data := &authData{}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
usr, errData, err := auth.Local(db, data.Username, data.Password)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(401, errData)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminPrimaryApprove,
audit.Fields{
"method": "local",
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
devAuth, secProviderId, errAudit, errData, err := validator.ValidateAdmin(
db, usr, false, c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
if errAudit == nil {
errAudit = audit.Fields{
"error": errData.Error,
"message": errData.Message,
}
}
errAudit["method"] = "local"
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
errAudit,
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
if devAuth {
deviceCount, err := device.CountSecondary(db, usr.Id)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
secType := ""
var secProvider bson.ObjectID
if deviceCount == 0 {
if secProviderId.IsZero() {
secType = secondary.AdminDeviceRegister
secProvider = secondary.DeviceProvider
} else {
secType = secondary.Admin
secProvider = secProviderId
}
} else {
secType = secondary.AdminDevice
secProvider = secondary.DeviceProvider
}
secd, err := secondary.New(db, usr.Id, secType, secProvider)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data, err := secd.GetData()
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(201, data)
return
} else if !secProviderId.IsZero() {
secd, err := secondary.New(db, usr.Id, secondary.Admin, secProviderId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data, err := secd.GetData()
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(201, data)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLogin,
audit.Fields{
"method": "local",
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
cook := cookie.NewAdmin(c.Writer, c.Request)
_, err = cook.NewSession(db, c.Request, usr.Id, true, session.Admin)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.Status(200)
}
type secondaryData struct {
Token string `json:"token"`
Factor string `json:"factor"`
Passcode string `json:"passcode"`
}
func authSecondaryPost(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
data := &secondaryData{}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
secd, err := secondary.Get(db, data.Token, secondary.Admin)
if err != nil {
if _, ok := err.(*database.NotFoundError); ok {
errData := &errortypes.ErrorData{
Error: "secondary_expired",
Message: "Secondary authentication has expired",
}
c.JSON(401, errData)
} else {
utils.AbortWithError(c, 500, err)
}
return
}
usr, err := secd.GetUser(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
errData, err := secd.Handle(db, c.Request, data.Factor, data.Passcode)
if err != nil {
if _, ok := err.(*secondary.IncompleteError); ok {
c.Status(201)
} else {
utils.AbortWithError(c, 500, err)
}
return
}
if errData != nil {
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
audit.Fields{
"method": "secondary",
"provider_id": secd.ProviderId,
"error": errData.Error,
"message": errData.Message,
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminSecondaryApprove,
audit.Fields{
"provider_id": secd.ProviderId,
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
deviceAuth, _, errAudit, errData, err := validator.ValidateAdmin(
db, usr, false, c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
if errAudit == nil {
errAudit = audit.Fields{
"error": errData.Error,
"message": errData.Message,
}
}
errAudit["method"] = "secondary"
errAudit["provider_id"] = secd.ProviderId
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
errAudit,
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
if deviceAuth {
deviceCount, err := device.CountSecondary(db, usr.Id)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if deviceCount == 0 {
secd, err := secondary.New(db, usr.Id,
secondary.AdminDeviceRegister, secondary.DeviceProvider)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data, err := secd.GetData()
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(201, data)
return
}
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLogin,
audit.Fields{
"method": "secondary",
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
cook := cookie.NewAdmin(c.Writer, c.Request)
_, err = cook.NewSession(db, c.Request, usr.Id, true, session.Admin)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.Status(200)
}
func logoutGet(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
authr := c.MustGet("authorizer").(*authorizer.Authorizer)
if authr.IsValid() {
err := authr.Remove(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
}
usr, _ := authr.GetUser(db)
if usr != nil {
err := audit.New(
db,
c.Request,
usr.Id,
audit.AdminLogout,
audit.Fields{},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
}
c.Redirect(302, "/login")
}
func authRequestGet(c *gin.Context) {
auth.Request(c, auth.Admin)
}
func authCallbackGet(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
sig := c.Query("sig")
query := strings.Split(c.Request.URL.RawQuery, "&sig=")[0]
usr, _, errAudit, errData, err := auth.Callback(db, sig, query)
if err != nil {
switch err.(type) {
case *auth.InvalidState:
c.Redirect(302, "/")
break
default:
utils.AbortWithError(c, 500, err)
}
return
}
if errData != nil {
if usr != nil {
if errAudit == nil {
errAudit = audit.Fields{
"error": errData.Error,
"message": errData.Message,
}
}
errAudit["method"] = "callback"
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
errAudit,
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
}
c.JSON(401, errData)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminPrimaryApprove,
audit.Fields{
"method": "callback",
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
devAuth, secProviderId, errAudit, errData, err := validator.ValidateAdmin(
db, usr, false, c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
if errAudit == nil {
errAudit = audit.Fields{
"error": errData.Error,
"message": errData.Message,
}
}
errAudit["method"] = "callback"
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
errAudit,
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
if devAuth {
deviceCount, err := device.CountSecondary(db, usr.Id)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
secType := ""
var secProvider bson.ObjectID
if deviceCount == 0 {
if secProviderId.IsZero() {
secType = secondary.AdminDeviceRegister
secProvider = secondary.DeviceProvider
} else {
secType = secondary.Admin
secProvider = secProviderId
}
} else {
secType = secondary.AdminDevice
secProvider = secondary.DeviceProvider
}
secd, err := secondary.New(db, usr.Id, secType, secProvider)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
urlQuery, err := secd.GetQuery()
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.Redirect(302, "/login?"+urlQuery)
return
} else if !secProviderId.IsZero() {
secd, err := secondary.New(db, usr.Id, secondary.Admin, secProviderId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
urlQuery, err := secd.GetQuery()
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.Redirect(302, "/login?"+urlQuery)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLogin,
audit.Fields{
"method": "callback",
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
cook := cookie.NewAdmin(c.Writer, c.Request)
_, err = cook.NewSession(db, c.Request, usr.Id, true, session.Admin)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.Redirect(302, "/")
}
func authWanRegisterGet(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
token := c.Query("token")
if node.Self.WebauthnDomain == "" {
errData := &errortypes.ErrorData{
Error: "webauthn_domain_unavailable",
Message: "WebAuthn domain must be configured",
}
c.JSON(400, errData)
return
}
secd, err := secondary.Get(db, token, secondary.AdminDeviceRegister)
if err != nil {
if _, ok := err.(*database.NotFoundError); ok {
errData := &errortypes.ErrorData{
Error: "secondary_expired",
Message: "Secondary authentication has expired",
}
c.JSON(401, errData)
} else {
utils.AbortWithError(c, 500, err)
}
return
}
usr, err := secd.GetUser(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminDeviceRegisterRequest,
audit.Fields{},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
resp, errData, err := secd.DeviceRegisterRequest(db,
utils.GetOrigin(c.Request))
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
audit.Fields{
"method": "device_register",
"error": errData.Error,
"message": errData.Message,
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
c.JSON(200, resp)
}
type authWanRegisterData struct {
Token string `json:"token"`
Name string `json:"name"`
}
func authWanRegisterPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &authWanRegisterData{}
body, err := utils.CopyBody(c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
err = c.Bind(data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
secd, err := secondary.Get(db, data.Token, secondary.AdminDeviceRegister)
if err != nil {
if _, ok := err.(*database.NotFoundError); ok {
errData := &errortypes.ErrorData{
Error: "secondary_expired",
Message: "Secondary authentication has expired",
}
c.JSON(401, errData)
} else {
utils.AbortWithError(c, 500, err)
}
return
}
usr, err := secd.GetUser(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
_, _, errAudit, errData, err := validator.ValidateAdmin(
db, usr, false, c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
if errAudit == nil {
errAudit = audit.Fields{
"error": errData.Error,
"message": errData.Message,
}
}
errAudit["method"] = "device_register"
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
errAudit,
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
devc, errData, err := secd.DeviceRegisterResponse(
db, utils.GetOrigin(c.Request), body, data.Name)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
err = audit.New(
db,
c.Request,
usr.Id,
audit.DeviceRegisterFailed,
audit.Fields{
"error": errData.Error,
"message": errData.Message,
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminDeviceRegister,
audit.Fields{
"device_id": devc.Id,
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "device.change")
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLogin,
audit.Fields{
"method": "device_register",
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
cook := cookie.NewAdmin(c.Writer, c.Request)
_, err = cook.NewSession(db, c.Request, usr.Id, true, session.Admin)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.Status(200)
}
func authWanRequestGet(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
token := c.Query("token")
secd, err := secondary.Get(db, token, secondary.AdminDevice)
if err != nil {
if _, ok := err.(*database.NotFoundError); ok {
errData := &errortypes.ErrorData{
Error: "secondary_expired",
Message: "Secondary authentication has expired",
}
c.JSON(401, errData)
} else {
utils.AbortWithError(c, 500, err)
}
return
}
usr, err := secd.GetUser(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
resp, errData, err := secd.DeviceRequest(
db, utils.GetOrigin(c.Request))
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
audit.Fields{
"method": "device",
"error": errData.Error,
"message": errData.Message,
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
c.JSON(200, resp)
}
type authWanRespondData struct {
Token string `json:"token"`
}
func authWanRespondPost(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
data := &authWanRespondData{}
body, err := utils.CopyBody(c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
err = c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
secd, err := secondary.Get(db, data.Token, secondary.AdminDevice)
if err != nil {
if _, ok := err.(*database.NotFoundError); ok {
errData := &errortypes.ErrorData{
Error: "secondary_expired",
Message: "Secondary authentication has expired",
}
c.JSON(401, errData)
} else {
utils.AbortWithError(c, 500, err)
}
return
}
usr, err := secd.GetUser(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
_, secProviderId, errAudit, errData, err := validator.ValidateAdmin(
db, usr, false, c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
if errAudit == nil {
errAudit = audit.Fields{
"error": errData.Error,
"message": errData.Message,
}
}
errAudit["method"] = "device"
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
errAudit,
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
errData, err = secd.DeviceRespond(
db, utils.GetOrigin(c.Request), body)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLoginFailed,
audit.Fields{
"method": "device",
"error": errData.Error,
"message": errData.Message,
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(401, errData)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminDeviceApprove,
audit.Fields{},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if !secProviderId.IsZero() {
secd, err := secondary.New(db, usr.Id, secondary.Admin,
secProviderId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data, err := secd.GetData()
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(201, data)
return
}
err = audit.New(
db,
c.Request,
usr.Id,
audit.AdminLogin,
audit.Fields{
"method": "device",
},
)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
cook := cookie.NewAdmin(c.Writer, c.Request)
_, err = cook.NewSession(db, c.Request, usr.Id, true, session.Admin)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.Status(200)
}
================================================
FILE: ahandlers/authority.go
================================================
package ahandlers
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/authority"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/utils"
)
type authorityData struct {
Id bson.ObjectID `json:"id"`
Name string `json:"name"`
Comment string `json:"comment"`
Type string `json:"type"`
Organization bson.ObjectID `json:"organization"`
Roles []string `json:"roles"`
Key string `json:"key"`
Principals []string `json:"principals"`
Certificate string `json:"certificate"`
}
type authoritiesData struct {
Authorities []*authority.Authority `json:"authorities"`
Count int64 `json:"count"`
}
func authorityPut(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &authorityData{}
authorityId, ok := utils.ParseObjectId(c.Param("authority_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
authr, err := authority.Get(db, authorityId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
authr.Name = data.Name
authr.Comment = data.Comment
authr.Type = data.Type
authr.Organization = data.Organization
authr.Roles = data.Roles
authr.Key = data.Key
authr.Principals = data.Principals
authr.Certificate = data.Certificate
fields := set.NewSet(
"name",
"comment",
"type",
"organization",
"roles",
"key",
"principals",
"certificate",
)
errData, err := authr.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = authr.CommitFields(db, fields)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "authority.change")
c.JSON(200, authr)
}
func authorityPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &authorityData{
Name: "new-authority",
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
authr := &authority.Authority{
Name: data.Name,
Comment: data.Comment,
Type: data.Type,
Organization: data.Organization,
Roles: data.Roles,
Key: data.Key,
Principals: data.Principals,
Certificate: data.Certificate,
}
errData, err := authr.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = authr.Insert(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "authority.change")
c.JSON(200, authr)
}
func authorityDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
authorityId, ok := utils.ParseObjectId(c.Param("authority_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := authority.Remove(db, authorityId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "authority.change")
c.JSON(200, nil)
}
func authoritiesDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := []bson.ObjectID{}
err := c.Bind(&data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
err = authority.RemoveMulti(db, data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "authority.change")
c.JSON(200, nil)
}
func authorityGet(c *gin.Context) {
if demo.IsDemo() {
authr := demo.Authorities[0]
c.JSON(200, authr)
return
}
db := c.MustGet("db").(*database.Database)
authorityId, ok := utils.ParseObjectId(c.Param("authority_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
authr, err := authority.Get(db, authorityId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, authr)
}
func authoritiesGet(c *gin.Context) {
if demo.IsDemo() {
data := &authoritiesData{
Authorities: demo.Authorities,
Count: int64(len(demo.Authorities)),
}
c.JSON(200, data)
return
}
db := c.MustGet("db").(*database.Database)
page, _ := strconv.ParseInt(c.Query("page"), 10, 0)
pageCount, _ := strconv.ParseInt(c.Query("page_count"), 10, 0)
query := bson.M{}
authrId, ok := utils.ParseObjectId(c.Query("id"))
if ok {
query["_id"] = authrId
}
name := strings.TrimSpace(c.Query("name"))
if name != "" {
query["name"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", regexp.QuoteMeta(name)),
"$options": "i",
}
}
role := strings.TrimSpace(c.Query("role"))
if role != "" {
if strings.HasPrefix(role, "~") {
role := role[1:]
if strings.HasPrefix(role, "!") {
query["roles"] = &bson.M{
"$not": &bson.M{
"$regex": fmt.Sprintf(".*%s.*",
regexp.QuoteMeta(role[1:])),
"$options": "i",
},
}
} else {
query["$or"] = []*bson.M{
&bson.M{
"roles": &bson.M{
"$regex": fmt.Sprintf(".*%s.*",
regexp.QuoteMeta(role)),
"$options": "i",
},
},
}
}
} else {
if strings.HasPrefix(role, "!") {
role = strings.TrimLeft(role, "!")
query["roles"] = &bson.M{
"$ne": role,
}
} else {
query["roles"] = role
}
}
}
principal := strings.TrimSpace(c.Query("principal"))
if principal != "" {
query["principals"] = principal
}
organization, ok := utils.ParseObjectId(c.Query("organization"))
if ok {
query["organization"] = organization
}
comment := strings.TrimSpace(c.Query("comment"))
if comment != "" {
query["comment"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", comment),
"$options": "i",
}
}
authorities, count, err := authority.GetAllPaged(
db, &query, page, pageCount)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data := &authoritiesData{
Authorities: authorities,
Count: count,
}
c.JSON(200, data)
}
================================================
FILE: ahandlers/balancer.go
================================================
package ahandlers
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/balancer"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/utils"
)
type balancerData struct {
Id bson.ObjectID `json:"id"`
Name string `json:"name"`
Comment string `json:"comment"`
State bool `json:"state"`
Type string `json:"type"`
Organization bson.ObjectID `json:"organization"`
Datacenter bson.ObjectID `json:"datacenter"`
Certificates []bson.ObjectID `json:"certificates"`
WebSockets bool `json:"websockets"`
Domains []*balancer.Domain `json:"domains"`
Backends []*balancer.Backend `json:"backends"`
CheckPath string `json:"check_path"`
}
type balancersData struct {
Balancers []*balancer.Balancer `json:"balancers"`
Count int64 `json:"count"`
}
func balancerPut(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &balancerData{}
balancerId, ok := utils.ParseObjectId(c.Param("balancer_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
balnc, err := balancer.Get(db, balancerId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
balnc.Name = data.Name
balnc.Comment = data.Comment
balnc.State = data.State
balnc.Type = data.Type
balnc.Organization = data.Organization
balnc.Datacenter = data.Datacenter
balnc.Certificates = data.Certificates
balnc.WebSockets = data.WebSockets
balnc.Domains = data.Domains
balnc.Backends = data.Backends
balnc.CheckPath = data.CheckPath
fields := set.NewSet(
"name",
"comment",
"state",
"type",
"organization",
"datacenter",
"certificates",
"websockets",
"domains",
"backends",
"check_path",
)
errData, err := balnc.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = balnc.CommitFields(db, fields)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "balancer.change")
balnc.Json()
c.JSON(200, balnc)
}
func balancerPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &balancerData{
Name: "new-balancer",
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
balnc := &balancer.Balancer{
Name: data.Name,
Comment: data.Comment,
State: data.State,
Type: data.Type,
Organization: data.Organization,
Datacenter: data.Datacenter,
Certificates: data.Certificates,
WebSockets: data.WebSockets,
Domains: data.Domains,
Backends: data.Backends,
CheckPath: data.CheckPath,
}
errData, err := balnc.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = balnc.Insert(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "balancer.change")
balnc.Json()
c.JSON(200, balnc)
}
func balancerDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
balancerId, ok := utils.ParseObjectId(c.Param("balancer_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := balancer.Remove(db, balancerId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "balancer.change")
c.JSON(200, nil)
}
func balancersDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := []bson.ObjectID{}
err := c.Bind(&data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
err = balancer.RemoveMulti(db, data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "balancer.change")
c.JSON(200, nil)
}
func balancerGet(c *gin.Context) {
if demo.IsDemo() {
balnc := demo.Balancers[0]
c.JSON(200, balnc)
return
}
db := c.MustGet("db").(*database.Database)
balancerId, ok := utils.ParseObjectId(c.Param("balancer_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
balnc, err := balancer.Get(db, balancerId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
balnc.Json()
c.JSON(200, balnc)
}
func balancersGet(c *gin.Context) {
if demo.IsDemo() {
data := &balancersData{
Balancers: demo.Balancers,
Count: int64(len(demo.Balancers)),
}
c.JSON(200, data)
return
}
db := c.MustGet("db").(*database.Database)
page, _ := strconv.ParseInt(c.Query("page"), 10, 0)
pageCount, _ := strconv.ParseInt(c.Query("page_count"), 10, 0)
query := bson.M{}
balancerId, ok := utils.ParseObjectId(c.Query("id"))
if ok {
query["_id"] = balancerId
}
name := strings.TrimSpace(c.Query("name"))
if name != "" {
query["name"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", regexp.QuoteMeta(name)),
"$options": "i",
}
}
organization, ok := utils.ParseObjectId(c.Query("organization"))
if ok {
query["organization"] = organization
}
datacenter, ok := utils.ParseObjectId(c.Query("datacenter"))
if ok {
query["datacenter"] = datacenter
}
comment := strings.TrimSpace(c.Query("comment"))
if comment != "" {
query["comment"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", comment),
"$options": "i",
}
}
balncs, count, err := balancer.GetAllPaged(db, &query, page, pageCount)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
for _, balnc := range balncs {
balnc.Json()
}
data := &balancersData{
Balancers: balncs,
Count: count,
}
c.JSON(200, data)
}
================================================
FILE: ahandlers/block.go
================================================
package ahandlers
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/aggregate"
"github.com/pritunl/pritunl-cloud/block"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/relations"
"github.com/pritunl/pritunl-cloud/utils"
)
type blockData struct {
Id bson.ObjectID `json:"id"`
Name string `json:"name"`
Comment string `json:"comment"`
Vlan int `json:"vlan"`
Type string `json:"type"`
Subnets []string `json:"subnets"`
Subnets6 []string `json:"subnets6"`
Excludes []string `json:"excludes"`
Netmask string `json:"netmask"`
Gateway string `json:"gateway"`
Gateway6 string `json:"gateway6"`
}
type blocksData struct {
Blocks []*aggregate.BlockAggregate `json:"blocks"`
Count int64 `json:"count"`
}
func blockPut(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
dta := &blockData{}
blckId, ok := utils.ParseObjectId(c.Param("block_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(dta)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
blck, err := block.Get(db, blckId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
blck.Name = dta.Name
blck.Comment = dta.Comment
blck.Vlan = dta.Vlan
blck.Subnets = dta.Subnets
blck.Subnets6 = dta.Subnets6
blck.Excludes = dta.Excludes
blck.Netmask = dta.Netmask
blck.Gateway = dta.Gateway
blck.Gateway6 = dta.Gateway6
fields := set.NewSet(
"name",
"comment",
"vlan",
"subnets",
"subnets6",
"excludes",
"netmask",
"gateway",
"gateway6",
)
errData, err := blck.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = blck.CommitFields(db, fields)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "block.change")
c.JSON(200, blck)
}
func blockPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
dta := &blockData{
Name: "new-block",
}
err := c.Bind(dta)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
blck := &block.Block{
Name: dta.Name,
Comment: dta.Comment,
Vlan: dta.Vlan,
Type: dta.Type,
Subnets: dta.Subnets,
Subnets6: dta.Subnets6,
Excludes: dta.Excludes,
Netmask: dta.Netmask,
Gateway: dta.Gateway,
Gateway6: dta.Gateway6,
}
errData, err := blck.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = blck.Insert(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "block.change")
c.JSON(200, blck)
}
func blockDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
blckId, ok := utils.ParseObjectId(c.Param("block_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
errData, err := relations.CanDelete(db, "block", blckId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = block.Remove(db, blckId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "block.change")
c.JSON(200, nil)
}
func blocksDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := []bson.ObjectID{}
err := c.Bind(&data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
errData, err := relations.CanDeleteAll(db, "block", data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = block.RemoveMulti(db, data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "block.change")
c.JSON(200, nil)
}
func blockGet(c *gin.Context) {
if demo.IsDemo() {
blck := demo.Blocks[0]
c.JSON(200, blck)
return
}
db := c.MustGet("db").(*database.Database)
blckId, ok := utils.ParseObjectId(c.Param("block_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
blck, err := block.Get(db, blckId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, blck)
}
func blocksGet(c *gin.Context) {
if demo.IsDemo() {
data := &blocksData{
Blocks: demo.Blocks,
Count: int64(len(demo.Blocks)),
}
c.JSON(200, data)
return
}
db := c.MustGet("db").(*database.Database)
page, _ := strconv.ParseInt(c.Query("page"), 10, 0)
pageCount, _ := strconv.ParseInt(c.Query("page_count"), 10, 0)
query := bson.M{}
blockId, ok := utils.ParseObjectId(c.Query("id"))
if ok {
query["_id"] = blockId
}
name := strings.TrimSpace(c.Query("name"))
if name != "" {
query["name"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", regexp.QuoteMeta(name)),
"$options": "i",
}
}
comment := strings.TrimSpace(c.Query("comment"))
if comment != "" {
query["comment"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", comment),
"$options": "i",
}
}
blcks, count, err := aggregate.GetBlockPaged(db, &query, page, pageCount)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data := &blocksData{
Blocks: blcks,
Count: count,
}
c.JSON(200, data)
}
================================================
FILE: ahandlers/certificate.go
================================================
package ahandlers
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/acme"
"github.com/pritunl/pritunl-cloud/certificate"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/relations"
"github.com/pritunl/pritunl-cloud/utils"
)
type certificateData struct {
Id bson.ObjectID `json:"id"`
Name string `json:"name"`
Comment string `json:"comment"`
Organization bson.ObjectID `json:"organization"`
Type string `json:"type"`
Key string `json:"key"`
Certificate string `json:"certificate"`
AcmeDomains []string `json:"acme_domains"`
AcmeType string `json:"acme_type"`
AcmeAuth string `json:"acme_auth"`
AcmeSecret bson.ObjectID `json:"acme_secret"`
Refresh bool `json:"refresh"`
}
type certificatesData struct {
Certificates []*certificate.Certificate `json:"certificates"`
Count int64 `json:"count"`
}
func certificatePut(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &certificateData{}
certId, ok := utils.ParseObjectId(c.Param("cert_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
cert, err := certificate.Get(db, certId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
cert.Name = data.Name
cert.Comment = data.Comment
cert.Organization = data.Organization
cert.Type = data.Type
cert.AcmeDomains = data.AcmeDomains
cert.AcmeType = data.AcmeType
cert.AcmeAuth = data.AcmeAuth
cert.AcmeSecret = data.AcmeSecret
fields := set.NewSet(
"name",
"comment",
"organization",
"type",
"acme_domains",
"acme_type",
"acme_auth",
"acme_secret",
"info",
)
if cert.Type != certificate.LetsEncrypt {
cert.Key = data.Key
fields.Add("key")
cert.Certificate = data.Certificate
fields.Add("certificate")
}
errData, err := cert.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = cert.CommitFields(db, fields)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if cert.Type == certificate.LetsEncrypt {
acme.RenewBackground(cert, data.Refresh)
}
event.PublishDispatch(db, "certificate.change")
c.JSON(200, cert)
}
func certificatePost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &certificateData{
Name: "new-certificate",
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
cert := &certificate.Certificate{
Name: data.Name,
Comment: data.Comment,
Organization: data.Organization,
Type: data.Type,
AcmeDomains: data.AcmeDomains,
AcmeType: data.AcmeType,
AcmeAuth: data.AcmeAuth,
AcmeSecret: data.AcmeSecret,
}
if cert.Type != certificate.LetsEncrypt {
cert.Key = data.Key
cert.Certificate = data.Certificate
}
errData, err := cert.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = cert.Insert(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if cert.Type == certificate.LetsEncrypt {
acme.RenewBackground(cert, false)
}
event.PublishDispatch(db, "certificate.change")
c.JSON(200, cert)
}
func certificateDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
certId, ok := utils.ParseObjectId(c.Param("cert_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
errData, err := relations.CanDelete(db, "certificate", certId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = certificate.Remove(db, certId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "certificate.change")
c.JSON(200, nil)
}
func certificatesDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := []bson.ObjectID{}
err := c.Bind(&data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
errData, err := relations.CanDeleteAll(db, "certificate", data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = certificate.RemoveMulti(db, data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "certificate.change")
c.JSON(200, nil)
}
func certificateGet(c *gin.Context) {
if demo.IsDemo() {
cert := demo.Certificates[0]
c.JSON(200, cert)
return
}
db := c.MustGet("db").(*database.Database)
certId, ok := utils.ParseObjectId(c.Param("cert_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
cert, err := certificate.Get(db, certId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if demo.IsDemo() {
cert.Key = "demo"
cert.AcmeAccount = "demo"
}
c.JSON(200, cert)
}
func certificatesGet(c *gin.Context) {
if demo.IsDemo() {
data := &certificatesData{
Certificates: demo.Certificates,
Count: int64(len(demo.Certificates)),
}
c.JSON(200, data)
return
}
db := c.MustGet("db").(*database.Database)
if c.Query("names") == "true" {
certs, err := certificate.GetAllNames(db, &bson.M{})
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, certs)
return
}
page, _ := strconv.ParseInt(c.Query("page"), 10, 0)
pageCount, _ := strconv.ParseInt(c.Query("page_count"), 10, 0)
query := bson.M{}
certificateId, ok := utils.ParseObjectId(c.Query("id"))
if ok {
query["_id"] = certificateId
}
name := strings.TrimSpace(c.Query("name"))
if name != "" {
query["name"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", regexp.QuoteMeta(name)),
"$options": "i",
}
}
organization, ok := utils.ParseObjectId(c.Query("organization"))
if ok {
query["organization"] = organization
}
comment := strings.TrimSpace(c.Query("comment"))
if comment != "" {
query["comment"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", comment),
"$options": "i",
}
}
certs, count, err := certificate.GetAllPaged(db, &query, page, pageCount)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data := &certificatesData{
Certificates: certs,
Count: count,
}
c.JSON(200, data)
}
================================================
FILE: ahandlers/check.go
================================================
package ahandlers
import (
"github.com/gin-gonic/gin"
)
func checkGet(c *gin.Context) {
c.String(200, "ok")
}
================================================
FILE: ahandlers/completion.go
================================================
package ahandlers
import (
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/block"
"github.com/pritunl/pritunl-cloud/certificate"
"github.com/pritunl/pritunl-cloud/completion"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/datacenter"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/domain"
"github.com/pritunl/pritunl-cloud/image"
"github.com/pritunl/pritunl-cloud/instance"
"github.com/pritunl/pritunl-cloud/node"
"github.com/pritunl/pritunl-cloud/plan"
"github.com/pritunl/pritunl-cloud/pod"
"github.com/pritunl/pritunl-cloud/pool"
"github.com/pritunl/pritunl-cloud/secret"
"github.com/pritunl/pritunl-cloud/shape"
"github.com/pritunl/pritunl-cloud/storage"
"github.com/pritunl/pritunl-cloud/unit"
"github.com/pritunl/pritunl-cloud/utils"
"github.com/pritunl/pritunl-cloud/vpc"
"github.com/pritunl/pritunl-cloud/zone"
)
func completionGet(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
if demo.IsDemo() {
data := &completion.Completion{}
for _, item := range demo.Organizations {
data.Organizations = append(data.Organizations, &database.Named{
Id: item.Id,
Name: item.Name,
})
}
for _, item := range demo.Authorities {
data.Authorities = append(data.Authorities, &database.Named{
Id: item.Id,
Name: item.Name,
})
}
for _, item := range demo.Policies {
data.Policies = append(data.Policies, &database.Named{
Id: item.Id,
Name: item.Name,
})
}
for _, item := range demo.Domains {
data.Domains = append(data.Domains, &domain.Completion{
Id: item.Id,
Name: item.Name,
Organization: item.Organization,
})
}
for _, item := range demo.Vpcs {
data.Vpcs = append(data.Vpcs, &vpc.Completion{
Id: item.Id,
Name: item.Name,
Organization: item.Organization,
VpcId: item.VpcId,
Network: item.Network,
Subnets: item.Subnets,
Datacenter: item.Datacenter,
})
}
for _, item := range demo.Datacenters {
data.Datacenters = append(data.Datacenters, &datacenter.Completion{
Id: item.Id,
Name: item.Name,
NetworkMode: item.NetworkMode,
})
}
for _, item := range demo.Blocks {
data.Blocks = append(data.Blocks, &block.Completion{
Id: item.Id,
Name: item.Name,
Type: item.Type,
})
}
for _, item := range demo.Nodes {
data.Nodes = append(data.Nodes, &node.Completion{
Id: item.Id,
Name: item.Name,
Zone: item.Zone,
Types: item.Types,
})
}
for _, item := range demo.Pools {
data.Pools = append(data.Pools, &pool.Completion{
Id: item.Id,
Name: item.Name,
Zone: item.Zone,
})
}
for _, item := range demo.Zones {
data.Zones = append(data.Zones, &zone.Completion{
Id: item.Id,
Datacenter: item.Datacenter,
Name: item.Name,
})
}
for _, item := range demo.Shapes {
data.Shapes = append(data.Shapes, &shape.Completion{
Id: item.Id,
Name: item.Name,
Datacenter: item.Datacenter,
Flexible: item.Flexible,
Memory: item.Memory,
Processors: item.Processors,
})
}
imgs, err := image.GetAllCompletion(db, &bson.M{})
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data.Images = imgs
for _, item := range demo.Storages {
data.Storages = append(data.Storages, &storage.Completion{
Id: item.Id,
Name: item.Name,
Type: item.Type,
})
}
for _, item := range demo.Instances {
data.Instances = append(data.Instances, &instance.Completion{
Id: item.Id,
Name: item.Name,
Organization: item.Organization,
Zone: item.Zone,
Vpc: item.Vpc,
Subnet: item.Subnet,
Node: item.Node,
})
}
for _, item := range demo.Plans {
data.Plans = append(data.Plans, &plan.Completion{
Id: item.Id,
Name: item.Name,
Organization: item.Organization,
})
}
for _, item := range demo.Certificates {
data.Certificates = append(
data.Certificates,
&certificate.Completion{
Id: item.Id,
Name: item.Name,
Organization: item.Organization,
Type: item.Type,
},
)
}
for _, item := range demo.Secrets {
data.Secrets = append(data.Secrets, &secret.Completion{
Id: item.Id,
Name: item.Name,
Organization: item.Organization,
Type: item.Type,
})
}
for _, item := range demo.Pods {
data.Pods = append(data.Pods, &pod.Completion{
Id: item.Id,
Name: item.Name,
Organization: item.Organization,
})
}
for _, item := range demo.Units {
data.Units = append(data.Units, &unit.Completion{
Id: item.Id,
Pod: item.Pod,
Organization: item.Organization,
Name: item.Name,
Kind: item.Kind,
})
}
c.JSON(200, data)
return
}
cmpl, err := completion.GetCompletion(db, bson.NilObjectID, nil)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, cmpl)
}
================================================
FILE: ahandlers/csrf.go
================================================
package ahandlers
import (
"github.com/gin-gonic/gin"
"github.com/pritunl/pritunl-cloud/authorizer"
"github.com/pritunl/pritunl-cloud/csrf"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/utils"
)
type csrfData struct {
Token string `json:"token"`
Theme string `json:"theme"`
EditorTheme string `json:"editor_theme"`
OracleLicense bool `json:"oracle_license"`
}
func csrfGet(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
authr := c.MustGet("authorizer").(*authorizer.Authorizer)
usr, err := authr.GetUser(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
token, err := csrf.NewToken(db, authr.SessionId())
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
oracleLicense := usr.OracleLicense
if demo.IsDemo() {
oracleLicense = true
}
data := &csrfData{
Token: token,
Theme: usr.Theme,
EditorTheme: usr.EditorTheme,
OracleLicense: oracleLicense,
}
c.JSON(200, data)
}
================================================
FILE: ahandlers/datacenter.go
================================================
package ahandlers
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/datacenter"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/relations"
"github.com/pritunl/pritunl-cloud/utils"
)
type datacenterData struct {
Id bson.ObjectID `json:"id"`
Name string `json:"name"`
Comment string `json:"comment"`
NetworkMode string `json:"network_mode"`
MatchOrganizations bool `json:"match_organizations"`
Organizations []bson.ObjectID `json:"organizations"`
JumboMtu int `json:"jumbo_mtu"`
PublicStorages []bson.ObjectID `json:"public_storages"`
PrivateStorage bson.ObjectID `json:"private_storage"`
PrivateStorageClass string `json:"private_storage_class"`
BackupStorage bson.ObjectID `json:"backup_storage"`
BackupStorageClass string `json:"backup_storage_class"`
}
type datacentersData struct {
Datacenters []*datacenter.Datacenter `json:"datacenters"`
Count int64 `json:"count"`
}
func datacenterPut(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &datacenterData{}
dcId, ok := utils.ParseObjectId(c.Param("dc_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
dc, err := datacenter.Get(db, dcId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
dc.Name = data.Name
dc.Comment = data.Comment
dc.NetworkMode = data.NetworkMode
dc.MatchOrganizations = data.MatchOrganizations
dc.Organizations = data.Organizations
dc.JumboMtu = data.JumboMtu
dc.PublicStorages = data.PublicStorages
dc.PrivateStorage = data.PrivateStorage
dc.PrivateStorageClass = data.PrivateStorageClass
dc.BackupStorage = data.BackupStorage
dc.BackupStorageClass = data.BackupStorageClass
fields := set.NewSet(
"name",
"comment",
"network_mode",
"match_organizations",
"organizations",
"jumbo_mtu",
"public_storages",
"private_storage",
"private_storage_class",
"backup_storage",
"backup_storage_class",
)
errData, err := dc.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = dc.CommitFields(db, fields)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "datacenter.change")
c.JSON(200, dc)
}
func datacenterPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &datacenterData{
Name: "new-datacenter",
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
dc := &datacenter.Datacenter{
Name: data.Name,
Comment: data.Comment,
NetworkMode: data.NetworkMode,
MatchOrganizations: data.MatchOrganizations,
Organizations: data.Organizations,
JumboMtu: data.JumboMtu,
PublicStorages: data.PublicStorages,
PrivateStorage: data.PrivateStorage,
PrivateStorageClass: data.PrivateStorageClass,
BackupStorage: data.BackupStorage,
BackupStorageClass: data.BackupStorageClass,
}
errData, err := dc.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = dc.Insert(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "datacenter.change")
c.JSON(200, dc)
}
func datacenterDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
dcId, ok := utils.ParseObjectId(c.Param("dc_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
errData, err := relations.CanDelete(db, "datacenter", dcId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = datacenter.Remove(db, dcId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "datacenter.change")
c.JSON(200, nil)
}
func datacentersDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := []bson.ObjectID{}
err := c.Bind(&data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
errData, err := relations.CanDeleteAll(db, "datacenter", data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = datacenter.RemoveMulti(db, data)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "datacenter.change")
c.JSON(200, nil)
}
func datacenterGet(c *gin.Context) {
if demo.IsDemo() {
dc := demo.Datacenters[0]
c.JSON(200, dc)
return
}
db := c.MustGet("db").(*database.Database)
dcId, ok := utils.ParseObjectId(c.Param("dc_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
dc, err := datacenter.Get(db, dcId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, dc)
}
func datacentersGet(c *gin.Context) {
if demo.IsDemo() {
data := &datacentersData{
Datacenters: demo.Datacenters,
Count: int64(len(demo.Datacenters)),
}
c.JSON(200, data)
return
}
db := c.MustGet("db").(*database.Database)
if c.Query("names") == "true" {
dcs, err := datacenter.GetAllNames(db, &bson.M{})
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, dcs)
return
}
page, _ := strconv.ParseInt(c.Query("page"), 10, 0)
pageCount, _ := strconv.ParseInt(c.Query("page_count"), 10, 0)
query := bson.M{}
datacenterId, ok := utils.ParseObjectId(c.Query("id"))
if ok {
query["_id"] = datacenterId
}
name := strings.TrimSpace(c.Query("name"))
if name != "" {
query["name"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", regexp.QuoteMeta(name)),
"$options": "i",
}
}
organization, ok := utils.ParseObjectId(c.Query("organization"))
if ok {
query["organization"] = organization
}
comment := strings.TrimSpace(c.Query("comment"))
if comment != "" {
query["comment"] = &bson.M{
"$regex": fmt.Sprintf(".*%s.*", comment),
"$options": "i",
}
}
dc, count, err := datacenter.GetAllPaged(db, &query, page, pageCount)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
data := &datacentersData{
Datacenters: dc,
Count: count,
}
c.JSON(200, data)
}
================================================
FILE: ahandlers/devices.go
================================================
package ahandlers
import (
"github.com/dropbox/godropbox/container/set"
"github.com/dropbox/godropbox/errors"
"github.com/gin-gonic/gin"
"github.com/pritunl/mongo-go-driver/v2/bson"
"github.com/pritunl/pritunl-cloud/alertevent"
"github.com/pritunl/pritunl-cloud/audit"
"github.com/pritunl/pritunl-cloud/authorizer"
"github.com/pritunl/pritunl-cloud/database"
"github.com/pritunl/pritunl-cloud/demo"
"github.com/pritunl/pritunl-cloud/device"
"github.com/pritunl/pritunl-cloud/errortypes"
"github.com/pritunl/pritunl-cloud/event"
"github.com/pritunl/pritunl-cloud/node"
"github.com/pritunl/pritunl-cloud/secondary"
"github.com/pritunl/pritunl-cloud/utils"
)
type deviceData struct {
User bson.ObjectID `json:"user"`
Name string `json:"name"`
Type string `json:"type"`
Mode string `json:"mode"`
Number string `json:"number"`
}
func devicePut(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &deviceData{}
devcId, ok := utils.ParseObjectId(c.Param("device_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
devc, err := device.Get(db, devcId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
devc.Name = data.Name
fields := set.NewSet(
"name",
)
errData, err := devc.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = devc.CommitFields(db, fields)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "device.change")
c.JSON(200, devc)
}
func devicePost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &deviceData{}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
devc := device.New(data.User, data.Type, data.Mode)
devc.Name = data.Name
devc.Number = data.Number
errData, err := devc.Validate(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
err = devc.Insert(db)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "device.change")
c.JSON(200, devc)
}
func deviceDelete(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
devcId, ok := utils.ParseObjectId(c.Param("device_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := device.Remove(db, devcId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "device.change")
c.JSON(200, nil)
}
func devicesGet(c *gin.Context) {
db := c.MustGet("db").(*database.Database)
usrId, ok := utils.ParseObjectId(c.Param("user_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
devices, err := device.GetAllSorted(db, usrId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
c.JSON(200, devices)
}
func deviceAlertPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
data := &deviceData{}
devcId, ok := utils.ParseObjectId(c.Param("resource_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
err := c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.AbortWithError(c, 500, err)
return
}
devc, err := device.Get(db, devcId)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
errData, err := alertevent.SendTest(db, devc)
if errData != nil {
c.JSON(400, errData)
return
}
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
event.PublishDispatch(db, "device.change")
c.JSON(200, devc)
}
func deviceMethodPost(c *gin.Context) {
switch c.Param("method") {
case "alert":
deviceAlertPost(c)
return
default:
utils.AbortWithStatus(c, 404)
return
}
return
}
type devicesWanRegisterRespData struct {
Token string `json:"token"`
Options interface{} `json:"options"`
}
func deviceWanRegisterGet(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
if node.Self.WebauthnDomain == "" {
errData := &errortypes.ErrorData{
Error: "webauthn_domain_unavailable",
Message: "WebAuthn domain must be configured",
}
c.JSON(400, errData)
return
}
usrId, ok := utils.ParseObjectId(c.Param("user_id"))
if !ok {
utils.AbortWithStatus(c, 400)
return
}
secd, err := secondary.New(db, usrId,
secondary.AdminDeviceRegister, secondary.DeviceProvider)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
jsonResp, errData, err := secd.DeviceRegisterRequest(db,
utils.GetOrigin(c.Request))
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
if errData != nil {
c.JSON(400, errData)
return
}
resp := &devicesWanRegisterRespData{
Token: secd.Id,
Options: jsonResp,
}
c.JSON(200, resp)
}
type devicesWanRegisterData struct {
Token string `json:"token"`
Name string `json:"name"`
}
func deviceWanRegisterPost(c *gin.Context) {
if demo.Blocked(c) {
return
}
db := c.MustGet("db").(*database.Database)
authr := c.MustGet("authorizer").(*authorizer.Authorizer)
data := &devicesWanRegisterData{}
body, err := utils.CopyBody(c.Request)
if err != nil {
utils.AbortWithError(c, 500, err)
return
}
err = c.Bind(data)
if err != nil {
err = &errortypes.ParseError{
errors.Wrap(err, "handler: Bind error"),
}
utils.A
gitextract_pa6e1wrf/
├── .gitattributes
├── .gitignore
├── CHANGES
├── LICENSE
├── README.md
├── acme/
│ ├── acme.go
│ ├── challenge.go
│ ├── constants.go
│ └── utils.go
├── advisory/
│ ├── advisory.go
│ ├── constants.go
│ └── utils.go
├── agent/
│ ├── agent.go
│ ├── constants/
│ │ └── constants.go
│ ├── imds/
│ │ ├── imds.go
│ │ ├── journal.go
│ │ ├── sync.go
│ │ └── utils.go
│ ├── logging/
│ │ ├── file.go
│ │ ├── handler.go
│ │ ├── logging.go
│ │ └── systemd.go
│ └── utils/
│ ├── sanitize.go
│ └── sys.go
├── aggregate/
│ ├── block.go
│ ├── deployment.go
│ ├── disk.go
│ ├── domain.go
│ ├── instance.go
│ ├── pod.go
│ └── shape.go
├── ahandlers/
│ ├── alert.go
│ ├── audit.go
│ ├── auth.go
│ ├── authority.go
│ ├── balancer.go
│ ├── block.go
│ ├── certificate.go
│ ├── check.go
│ ├── completion.go
│ ├── csrf.go
│ ├── datacenter.go
│ ├── devices.go
│ ├── disk.go
│ ├── domain.go
│ ├── event.go
│ ├── firewall.go
│ ├── handlers.go
│ ├── image.go
│ ├── instance.go
│ ├── license.go
│ ├── log.go
│ ├── node.go
│ ├── organization.go
│ ├── plan.go
│ ├── pod.go
│ ├── policy.go
│ ├── pool.go
│ ├── relations.go
│ ├── secret.go
│ ├── session.go
│ ├── settings.go
│ ├── shape.go
│ ├── static.go
│ ├── storage.go
│ ├── subscription.go
│ ├── theme.go
│ ├── user.go
│ ├── vpc.go
│ └── zone.go
├── alert/
│ ├── alert.go
│ ├── constants.go
│ └── utils.go
├── alertevent/
│ ├── alertevent.go
│ └── utils.go
├── arp/
│ └── arp.go
├── audit/
│ ├── audit.go
│ ├── constants.go
│ └── utils.go
├── auth/
│ ├── auth.go
│ ├── authzero.go
│ ├── azure.go
│ ├── constants.go
│ ├── errortypes.go
│ ├── google.go
│ ├── handler.go
│ ├── jumpcloud.go
│ ├── saml.go
│ ├── state.go
│ ├── sync.go
│ └── utils.go
├── authority/
│ ├── authority.go
│ ├── constants.go
│ └── utils.go
├── authorizer/
│ ├── authorizer.go
│ ├── constants.go
│ └── utils.go
├── backup/
│ └── backup.go
├── balancer/
│ ├── balancer.go
│ ├── constants.go
│ └── utils.go
├── block/
│ ├── block.go
│ ├── constants.go
│ ├── errortypes.go
│ ├── ip.go
│ └── utils.go
├── bridges/
│ └── bridges.go
├── certificate/
│ ├── certificate.go
│ ├── constants.go
│ └── utils.go
├── cloud/
│ ├── cloud.go
│ └── oracle.go
├── cloudinit/
│ ├── cloudinit.go
│ ├── query.go
│ └── utils.go
├── cmd/
│ ├── backup.go
│ ├── dhcp.go
│ ├── imds.go
│ ├── instance.go
│ ├── log.go
│ ├── mtu.go
│ ├── node.go
│ ├── optimize.go
│ └── settings.go
├── colorize/
│ └── colorize.go
├── completion/
│ └── completion.go
├── compositor/
│ └── compositor.go
├── config/
│ └── config.go
├── constants/
│ └── constants.go
├── cookie/
│ ├── cookie.go
│ └── utils.go
├── crypto/
│ └── crypto.go
├── csrf/
│ └── csrf.go
├── data/
│ ├── disk.go
│ ├── image.go
│ ├── resize.go
│ ├── sync.go
│ └── utils.go
├── database/
│ ├── base.go
│ ├── client.go
│ ├── collection.go
│ ├── database.go
│ ├── errors.go
│ ├── index.go
│ └── utils.go
├── datacenter/
│ ├── constants.go
│ ├── datacenter.go
│ └── utils.go
├── defaults/
│ └── defaults.go
├── demo/
│ ├── alert.go
│ ├── authority.go
│ ├── balancer.go
│ ├── block.go
│ ├── certificate.go
│ ├── datacenter.go
│ ├── demo.go
│ ├── disk.go
│ ├── domain.go
│ ├── firewall.go
│ ├── instance.go
│ ├── log.go
│ ├── node.go
│ ├── organization.go
│ ├── plan.go
│ ├── pod.go
│ ├── policy.go
│ ├── pool.go
│ ├── rand.go
│ ├── secret.go
│ ├── shape.go
│ ├── storage.go
│ ├── subscription.go
│ ├── user.go
│ ├── vpc.go
│ └── zone.go
├── deploy/
│ ├── deploy.go
│ ├── deployments.go
│ ├── disks.go
│ ├── imds.go
│ ├── instances.go
│ ├── ipset.go
│ ├── iptables.go
│ ├── namespace.go
│ ├── network.go
│ └── services.go
├── deployment/
│ ├── constants.go
│ ├── deployment.go
│ └── utils.go
├── device/
│ ├── constants.go
│ ├── device.go
│ ├── facet.go
│ └── utils.go
├── dhcpc/
│ ├── constants.go
│ ├── dhcpc.go
│ ├── imds.go
│ ├── lease.go
│ ├── lease4.go
│ ├── lease6.go
│ ├── systemd.go
│ └── utils.go
├── dhcps/
│ ├── dhcp4.go
│ ├── dhcp6.go
│ ├── ndp.go
│ └── systemd.go
├── disk/
│ ├── constants.go
│ ├── disk.go
│ ├── sort.go
│ └── utils.go
├── dns/
│ ├── aws.go
│ ├── cloudflare.go
│ ├── constants.go
│ ├── dns.go
│ ├── errors.go
│ ├── google.go
│ ├── oracle.go
│ └── utils.go
├── dnss/
│ ├── constants.go
│ ├── database.go
│ ├── dnss.go
│ ├── plugin.go
│ └── response.go
├── domain/
│ ├── constants.go
│ ├── domain.go
│ ├── record.go
│ ├── sort.go
│ └── utils.go
├── drive/
│ ├── drive.go
│ └── utils.go
├── engine/
│ ├── bash.go
│ ├── constants.go
│ ├── engine.go
│ ├── parser.go
│ └── python.go
├── errortypes/
│ └── errortypes.go
├── eval/
│ ├── constants.go
│ ├── errortypes.go
│ ├── eval.go
│ └── utils.go
├── event/
│ ├── event.go
│ ├── listener.go
│ └── socket.go
├── features/
│ ├── qemu.go
│ └── systemd.go
├── finder/
│ ├── constants.go
│ └── resources.go
├── firewall/
│ ├── constants.go
│ ├── firewall.go
│ ├── spec.go
│ └── utils.go
├── geo/
│ └── geo.go
├── go.mod
├── go.sum
├── guest/
│ ├── guest.go
│ └── power.go
├── hnetwork/
│ ├── hnetwork.go
│ └── utils.go
├── hugepages/
│ └── hugepages.go
├── image/
│ ├── constants.go
│ ├── errortypes.go
│ ├── image.go
│ ├── sort.go
│ └── utils.go
├── imds/
│ ├── config.go
│ ├── imds.go
│ ├── resource/
│ │ ├── resource.go
│ │ └── utils.go
│ ├── server/
│ │ ├── config/
│ │ │ └── config.go
│ │ ├── constants/
│ │ │ └── constants.go
│ │ ├── errortypes/
│ │ │ └── errortypes.go
│ │ ├── handlers/
│ │ │ ├── certificate.go
│ │ │ ├── dhcp.go
│ │ │ ├── handlers.go
│ │ │ ├── instance.go
│ │ │ ├── node.go
│ │ │ ├── query.go
│ │ │ ├── secret.go
│ │ │ ├── sync.go
│ │ │ └── vpc.go
│ │ ├── router/
│ │ │ └── router.go
│ │ ├── server.go
│ │ ├── state/
│ │ │ └── state.go
│ │ └── utils/
│ │ ├── files.go
│ │ ├── misc.go
│ │ └── request.go
│ ├── systemd.go
│ └── types/
│ ├── certificate.go
│ ├── config.go
│ ├── constants.go
│ ├── domain.go
│ ├── instance.go
│ ├── journal.go
│ ├── node.go
│ ├── pod.go
│ ├── secret.go
│ ├── state.go
│ └── vpc.go
├── info/
│ └── instance.go
├── instance/
│ ├── constants.go
│ ├── errortypes.go
│ ├── instance.go
│ └── utils.go
├── interfaces/
│ └── interfaces.go
├── ip/
│ ├── interface.go
│ └── ip.go
├── iproute/
│ ├── address.go
│ ├── bridge.go
│ └── iface.go
├── ipset/
│ ├── names.go
│ ├── sets.go
│ ├── state.go
│ └── utils.go
├── iptables/
│ ├── iptables.go
│ ├── lock.go
│ ├── rules.go
│ ├── state.go
│ ├── update.go
│ └── utils.go
├── ipvs/
│ ├── constants.go
│ ├── ipvs.go
│ ├── service.go
│ └── target.go
├── iscsi/
│ └── iscsi.go
├── iso/
│ └── iso.go
├── journal/
│ ├── constants.go
│ ├── journal.go
│ ├── store.go
│ └── utils.go
├── lock/
│ └── lvm.go
├── log/
│ ├── constants.go
│ ├── log.go
│ └── utils.go
├── logger/
│ ├── database.go
│ ├── file.go
│ ├── formatter.go
│ ├── hook.go
│ ├── limiter.go
│ ├── logger.go
│ ├── sender.go
│ └── writer.go
├── lvm/
│ ├── lv.go
│ └── vgs.go
├── main.go
├── middlewear/
│ ├── gzip.go
│ └── middlewear.go
├── mtu/
│ └── mtu.go
├── netconf/
│ ├── address.go
│ ├── base.go
│ ├── bridge.go
│ ├── clear.go
│ ├── external.go
│ ├── host.go
│ ├── iface.go
│ ├── imds.go
│ ├── internal.go
│ ├── ip.go
│ ├── netconf.go
│ ├── nodeport.go
│ ├── oracle.go
│ ├── space.go
│ ├── utils.go
│ ├── validate.go
│ └── vlan.go
├── node/
│ ├── block.go
│ ├── certificate.go
│ ├── constants.go
│ ├── interfaces.go
│ ├── node.go
│ ├── oracle.go
│ └── utils.go
├── nodeport/
│ ├── constants.go
│ ├── mapping.go
│ ├── network.go
│ ├── nodeport.go
│ └── utils.go
├── nonce/
│ └── nonce.go
├── notification/
│ └── notification.go
├── oracle/
│ ├── iface.go
│ ├── metadata.go
│ ├── oracle.go
│ ├── provider.go
│ ├── routetable.go
│ ├── subnet.go
│ ├── utils.go
│ └── vnic.go
├── organization/
│ ├── organization.go
│ └── utils.go
├── paths/
│ ├── paths.go
│ └── utils.go
├── pci/
│ ├── pci.go
│ └── utils.go
├── permission/
│ ├── permission.go
│ └── user.go
├── plan/
│ ├── constants.go
│ ├── data.go
│ ├── plan.go
│ └── utils.go
├── planner/
│ ├── planner.go
│ └── utils.go
├── pod/
│ ├── pod.go
│ └── utils.go
├── policy/
│ ├── constants.go
│ ├── policy.go
│ └── utils.go
├── pool/
│ ├── constants.go
│ ├── pool.go
│ └── utils.go
├── proxy/
│ ├── constants.go
│ ├── domain.go
│ ├── errortypes.go
│ ├── proxy.go
│ ├── resolver.go
│ ├── reverse.go
│ ├── transport.go
│ ├── types.go
│ ├── utils.go
│ └── ws.go
├── qemu/
│ ├── constants.go
│ ├── data.go
│ ├── disk.go
│ ├── manage.go
│ ├── network.go
│ ├── power.go
│ ├── qemu.go
│ ├── routes.go
│ ├── sort.go
│ ├── usb.go
│ └── utils.go
├── qga/
│ └── qga.go
├── qmp/
│ ├── backup.go
│ ├── disk.go
│ ├── errors.go
│ ├── password.go
│ ├── power.go
│ ├── qmp.go
│ └── vnc.go
├── qms/
│ ├── disk.go
│ ├── power.go
│ ├── qms.go
│ ├── usb.go
│ ├── utils.go
│ └── vnc.go
├── redirect/
│ ├── acme.go
│ ├── crypto/
│ │ └── crypto.go
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ └── utils.go
├── relations/
│ ├── definitions/
│ │ ├── block.go
│ │ ├── certificate.go
│ │ ├── datacenter.go
│ │ ├── definitions.go
│ │ ├── firewall.go
│ │ ├── instance.go
│ │ ├── node.go
│ │ ├── organization.go
│ │ ├── pod.go
│ │ ├── policy.go
│ │ ├── secret.go
│ │ ├── shape.go
│ │ ├── vpc.go
│ │ └── zone.go
│ ├── registry.go
│ ├── relations.go
│ ├── response.go
│ └── utils.go
├── render/
│ ├── constants.go
│ └── render.go
├── requires/
│ ├── errors.go
│ └── requires.go
├── rokey/
│ ├── cache.go
│ ├── rokey.go
│ └── utils.go
├── router/
│ ├── certificates.go
│ ├── constants.go
│ └── router.go
├── scheduler/
│ ├── constants.go
│ ├── scheduler.go
│ ├── unit.go
│ └── utils.go
├── secondary/
│ ├── constants.go
│ ├── duo.go
│ ├── errors.go
│ ├── okta.go
│ ├── onelogin.go
│ ├── secondary.go
│ └── utils.go
├── secret/
│ ├── constants.go
│ ├── oracle.go
│ ├── secret.go
│ └── utils.go
├── session/
│ ├── constants.go
│ ├── session.go
│ └── utils.go
├── settings/
│ ├── acme.go
│ ├── auth.go
│ ├── hypervisor.go
│ ├── local.go
│ ├── registry.go
│ ├── router.go
│ ├── settings.go
│ ├── system.go
│ └── telemetry.go
├── setup/
│ └── iptables.go
├── shape/
│ ├── constants.go
│ ├── node.go
│ ├── shape.go
│ └── utils.go
├── signature/
│ ├── signature.go
│ └── utils.go
├── spec/
│ ├── constants.go
│ ├── domain.go
│ ├── firewall.go
│ ├── instance.go
│ ├── journal.go
│ ├── node.go
│ ├── spec.go
│ └── utils.go
├── state/
│ ├── arps.go
│ ├── authorities.go
│ ├── authorities_preload.go
│ ├── datacenter.go
│ ├── deployments.go
│ ├── disks.go
│ ├── domains.go
│ ├── firewalls.go
│ ├── firewalls_preload.go
│ ├── instances.go
│ ├── instances_preload.go
│ ├── network.go
│ ├── package.go
│ ├── pools.go
│ ├── runtimes.go
│ ├── schedulers.go
│ ├── state.go
│ ├── state_old.go
│ ├── virtuals.go
│ ├── vpcs.go
│ ├── zone.go
│ └── zones.go
├── static/
│ ├── file.go
│ └── static.go
├── storage/
│ ├── constants.go
│ ├── storage.go
│ └── utils.go
├── store/
│ ├── address.go
│ ├── arp.go
│ ├── disks.go
│ ├── routes.go
│ ├── usb.go
│ └── virt.go
├── subscription/
│ └── subscription.go
├── sync/
│ ├── auth.go
│ ├── nodes.go
│ ├── sync.go
│ └── vm.go
├── systemd/
│ ├── systemd.go
│ └── utils.go
├── task/
│ ├── acme.go
│ ├── advisory.go
│ ├── backing.go
│ ├── balancer.go
│ ├── blocks.go
│ ├── cache.go
│ ├── constants.go
│ ├── deployments.go
│ ├── domains.go
│ ├── imds.go
│ ├── job.go
│ ├── notification.go
│ ├── scheduler.go
│ ├── spec.go
│ ├── specindex.go
│ ├── storage.go
│ └── task.go
├── telemetry/
│ ├── constants.go
│ ├── telemetry.go
│ ├── updates.go
│ └── utils.go
├── tools/
│ ├── autoindex.py
│ ├── build_run.sh
│ ├── builder.py
│ ├── generate_demo_data.py
│ ├── generate_files.py
│ ├── package/
│ │ ├── PKGBUILD
│ │ └── README.md
│ ├── pritunl-cloud-redirect.service
│ ├── pritunl-cloud-redirect.socket
│ ├── pritunl-cloud.service
│ ├── tsc_run.sh
│ ├── virt-install/
│ │ ├── README.md
│ │ ├── download.sh
│ │ ├── install/
│ │ │ ├── almalinux10.sh
│ │ │ ├── almalinux8.sh
│ │ │ ├── almalinux9.sh
│ │ │ ├── alpinelinux.sh
│ │ │ ├── archlinux.sh
│ │ │ ├── fedora43.sh
│ │ │ ├── fedora44.sh
│ │ │ ├── freebsd.sh
│ │ │ ├── oraclelinux10.sh
│ │ │ ├── oraclelinux7.sh
│ │ │ ├── oraclelinux8.sh
│ │ │ ├── oraclelinux9.sh
│ │ │ ├── rockylinux10.sh
│ │ │ ├── rockylinux8.sh
│ │ │ ├── rockylinux9.sh
│ │ │ ├── ubuntu24.sh
│ │ │ └── ubuntu26.sh
│ │ └── setup/
│ │ ├── alpine.sh
│ │ ├── arch.sh
│ │ ├── debian.sh
│ │ ├── fedora.sh
│ │ ├── freebsd.sh
│ │ ├── rhel10.sh
│ │ ├── rhel7.sh
│ │ ├── rhel8.sh
│ │ └── rhel9.sh
│ └── webpack_run.sh
├── tpm/
│ ├── tpm.go
│ └── utils.go
├── twilio/
│ ├── twilio.go
│ └── utils.go
├── uhandlers/
│ ├── alert.go
│ ├── auth.go
│ ├── authority.go
│ ├── balancer.go
│ ├── certificate.go
│ ├── check.go
│ ├── completion.go
│ ├── csrf.go
│ ├── datacenter.go
│ ├── devices.go
│ ├── disk.go
│ ├── domain.go
│ ├── event.go
│ ├── firewall.go
│ ├── handlers.go
│ ├── image.go
│ ├── instance.go
│ ├── license.go
│ ├── node.go
│ ├── organization.go
│ ├── plan.go
│ ├── pod.go
│ ├── pool.go
│ ├── relations.go
│ ├── secret.go
│ ├── shape.go
│ ├── static.go
│ ├── theme.go
│ ├── utils.go
│ ├── vpc.go
│ └── zone.go
├── unit/
│ ├── unit.go
│ └── utils.go
├── upgrade/
│ ├── created.go
│ ├── instance.go
│ ├── journal.go
│ ├── node.go
│ ├── objectid.go
│ ├── roles.go
│ ├── state.go
│ ├── upgrade.go
│ └── zone_datacenter.go
├── usb/
│ ├── usb.go
│ └── utils.go
├── user/
│ ├── constants.go
│ ├── user.go
│ └── utils.go
├── useragent/
│ └── useragent.go
├── utils/
│ ├── crypto.go
│ ├── dns.go
│ ├── files.go
│ ├── filter.go
│ ├── limiter.go
│ ├── math.go
│ ├── misc.go
│ ├── multilock.go
│ ├── multitimeoutlock.go
│ ├── network.go
│ ├── proc.go
│ ├── prompt.go
│ ├── psutil_freebsd.go
│ ├── psutil_linux.go
│ ├── randomname.go
│ ├── request.go
│ ├── sort.go
│ ├── timeoutlock.go
│ ├── unix.go
│ └── webauthn.go
├── validator/
│ └── validator.go
├── version/
│ ├── cache.go
│ ├── utils.go
│ └── version.go
├── virtiofs/
│ ├── systemd.go
│ ├── utils.go
│ └── virtiofs.go
├── vm/
│ ├── constants.go
│ ├── sort.go
│ ├── utils.go
│ └── vm.go
├── vmdk/
│ └── utils.go
├── vpc/
│ ├── constants.go
│ ├── ip.go
│ ├── subnet.go
│ ├── utils.go
│ └── vpc.go
├── vxlan/
│ └── vxlan.go
├── www/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── Alert.ts
│ │ ├── App.tsx
│ │ ├── Constants.ts
│ │ ├── Csrf.ts
│ │ ├── EditorThemes.ts
│ │ ├── Event.ts
│ │ ├── EventEmitter.ts
│ │ ├── License.ts
│ │ ├── Loader.ts
│ │ ├── References.d.ts
│ │ ├── Router.ts
│ │ ├── Styles.tsx
│ │ ├── Theme.ts
│ │ ├── actions/
│ │ │ ├── AlertActions.ts
│ │ │ ├── AuditActions.ts
│ │ │ ├── AuthorityActions.ts
│ │ │ ├── BalancerActions.ts
│ │ │ ├── BlockActions.ts
│ │ │ ├── CertificateActions.ts
│ │ │ ├── CompletionActions.ts
│ │ │ ├── DatacenterActions.ts
│ │ │ ├── DeviceActions.ts
│ │ │ ├── DiskActions.ts
│ │ │ ├── DomainActions.ts
│ │ │ ├── FirewallActions.ts
│ │ │ ├── ImageActions.ts
│ │ │ ├── InstanceActions.ts
│ │ │ ├── LogActions.ts
│ │ │ ├── NodeActions.ts
│ │ │ ├── OrganizationActions.ts
│ │ │ ├── PlanActions.ts
│ │ │ ├── PodActions.ts
│ │ │ ├── PolicyActions.ts
│ │ │ ├── PoolActions.ts
│ │ │ ├── RelationsActions.ts
│ │ │ ├── SecretActions.ts
│ │ │ ├── SessionActions.ts
│ │ │ ├── SettingsActions.ts
│ │ │ ├── ShapeActions.ts
│ │ │ ├── StorageActions.ts
│ │ │ ├── SubscriptionActions.ts
│ │ │ ├── UserActions.ts
│ │ │ ├── VpcActions.ts
│ │ │ └── ZoneActions.ts
│ │ ├── completion/
│ │ │ ├── Cache.ts
│ │ │ ├── Engine.ts
│ │ │ └── Types.ts
│ │ ├── components/
│ │ │ ├── AdvisoryDialog.tsx
│ │ │ ├── Alert.tsx
│ │ │ ├── AlertDetailed.tsx
│ │ │ ├── AlertNew.tsx
│ │ │ ├── Alerts.tsx
│ │ │ ├── AlertsFilter.tsx
│ │ │ ├── AlertsPage.tsx
│ │ │ ├── Audit.tsx
│ │ │ ├── Audits.tsx
│ │ │ ├── AuditsPage.tsx
│ │ │ ├── Authorities.tsx
│ │ │ ├── AuthoritiesFilter.tsx
│ │ │ ├── AuthoritiesPage.tsx
│ │ │ ├── Authority.tsx
│ │ │ ├── AuthorityDetailed.tsx
│ │ │ ├── AuthorityNew.tsx
│ │ │ ├── Balancer.tsx
│ │ │ ├── BalancerBackend.tsx
│ │ │ ├── BalancerDetailed.tsx
│ │ │ ├── BalancerDomain.tsx
│ │ │ ├── BalancerNew.tsx
│ │ │ ├── Balancers.tsx
│ │ │ ├── BalancersFilter.tsx
│ │ │ ├── BalancersPage.tsx
│ │ │ ├── Block.tsx
│ │ │ ├── BlockDetailed.tsx
│ │ │ ├── BlockNew.tsx
│ │ │ ├── Blocks.tsx
│ │ │ ├── BlocksFilter.tsx
│ │ │ ├── BlocksPage.tsx
│ │ │ ├── Certificate.tsx
│ │ │ ├── CertificateDetailed.tsx
│ │ │ ├── CertificateDomain.tsx
│ │ │ ├── CertificateNew.tsx
│ │ │ ├── Certificates.tsx
│ │ │ ├── CertificatesFilter.tsx
│ │ │ ├── CertificatesPage.tsx
│ │ │ ├── ConfirmButton.tsx
│ │ │ ├── CopyButton.tsx
│ │ │ ├── Datacenter.tsx
│ │ │ ├── DatacenterDetailed.tsx
│ │ │ ├── DatacenterNew.tsx
│ │ │ ├── Datacenters.tsx
│ │ │ ├── DatacentersFilter.tsx
│ │ │ ├── DatacentersPage.tsx
│ │ │ ├── Device.tsx
│ │ │ ├── Devices.tsx
│ │ │ ├── Disk.tsx
│ │ │ ├── DiskDetailed.tsx
│ │ │ ├── DiskNew.tsx
│ │ │ ├── Disks.tsx
│ │ │ ├── DisksFilter.tsx
│ │ │ ├── DisksPage.tsx
│ │ │ ├── Domain.tsx
│ │ │ ├── DomainDetailed.tsx
│ │ │ ├── DomainNew.tsx
│ │ │ ├── DomainRecord.tsx
│ │ │ ├── Domains.tsx
│ │ │ ├── DomainsFilter.tsx
│ │ │ ├── DomainsPage.tsx
│ │ │ ├── Editor.tsx
│ │ │ ├── Firewall.tsx
│ │ │ ├── FirewallDetailed.tsx
│ │ │ ├── FirewallNew.tsx
│ │ │ ├── FirewallRule.tsx
│ │ │ ├── Firewalls.tsx
│ │ │ ├── FirewallsFilter.tsx
│ │ │ ├── FirewallsPage.tsx
│ │ │ ├── Help.tsx
│ │ │ ├── Image.tsx
│ │ │ ├── ImageDetailed.tsx
│ │ │ ├── Images.tsx
│ │ │ ├── ImagesFilter.tsx
│ │ │ ├── ImagesPage.tsx
│ │ │ ├── Instance.tsx
│ │ │ ├── InstanceDetailed.tsx
│ │ │ ├── InstanceImages.tsx
│ │ │ ├── InstanceIscsiDevice.tsx
│ │ │ ├── InstanceLicense.tsx
│ │ │ ├── InstanceMount.tsx
│ │ │ ├── InstanceNew.tsx
│ │ │ ├── InstanceNodePort.tsx
│ │ │ ├── Instances.tsx
│ │ │ ├── InstancesFilter.tsx
│ │ │ ├── InstancesPage.tsx
│ │ │ ├── LoadingBar.tsx
│ │ │ ├── LoadingCircle.tsx
│ │ │ ├── Log.tsx
│ │ │ ├── LogViewer.tsx
│ │ │ ├── Logs.tsx
│ │ │ ├── LogsFilter.tsx
│ │ │ ├── LogsPage.tsx
│ │ │ ├── Main.tsx
│ │ │ ├── MarkdownMemo.tsx
│ │ │ ├── Node.tsx
│ │ │ ├── NodeBlock.tsx
│ │ │ ├── NodeDeploy.tsx
│ │ │ ├── NodeDetailed.tsx
│ │ │ ├── NodeShare.tsx
│ │ │ ├── Nodes.tsx
│ │ │ ├── NodesFilter.tsx
│ │ │ ├── NodesPage.tsx
│ │ │ ├── NonState.tsx
│ │ │ ├── Organization.tsx
│ │ │ ├── OrganizationDetailed.tsx
│ │ │ ├── OrganizationNew.tsx
│ │ │ ├── OrganizationSelect.tsx
│ │ │ ├── Organizations.tsx
│ │ │ ├── OrganizationsFilter.tsx
│ │ │ ├── OrganizationsPage.tsx
│ │ │ ├── Page.tsx
│ │ │ ├── PageButton.tsx
│ │ │ ├── PageCreate.tsx
│ │ │ ├── PageCustom.tsx
│ │ │ ├── PageDateTime.tsx
│ │ │ ├── PageHeader.tsx
│ │ │ ├── PageInfo.tsx
│ │ │ ├── PageInput.tsx
│ │ │ ├── PageInputButton.tsx
│ │ │ ├── PageInputSwitch.tsx
│ │ │ ├── PageNew.tsx
│ │ │ ├── PageNumInput.tsx
│ │ │ ├── PagePanel.tsx
│ │ │ ├── PageSave.tsx
│ │ │ ├── PageSelect.tsx
│ │ │ ├── PageSelectButton.tsx
│ │ │ ├── PageSelectButtonConfirm.tsx
│ │ │ ├── PageSelector.tsx
│ │ │ ├── PageSplit.tsx
│ │ │ ├── PageSwitch.tsx
│ │ │ ├── PageTextArea.tsx
│ │ │ ├── Plan.tsx
│ │ │ ├── PlanDetailed.tsx
│ │ │ ├── PlanEditor.tsx
│ │ │ ├── PlanNew.tsx
│ │ │ ├── PlanStatement.tsx
│ │ │ ├── Plans.tsx
│ │ │ ├── PlansFilter.tsx
│ │ │ ├── PlansPage.tsx
│ │ │ ├── Pod.tsx
│ │ │ ├── PodDeploy.tsx
│ │ │ ├── PodDeployment.tsx
│ │ │ ├── PodDeploymentEdit.tsx
│ │ │ ├── PodDetailed.tsx
│ │ │ ├── PodEditor.tsx
│ │ │ ├── PodMigrate.tsx
│ │ │ ├── PodNew.tsx
│ │ │ ├── PodUnit.tsx
│ │ │ ├── PodWorkspace.tsx
│ │ │ ├── Pods.tsx
│ │ │ ├── PodsFilter.tsx
│ │ │ ├── PodsPage.tsx
│ │ │ ├── Policies.tsx
│ │ │ ├── PoliciesFilter.tsx
│ │ │ ├── PoliciesPage.tsx
│ │ │ ├── Policy.tsx
│ │ │ ├── PolicyDetailed.tsx
│ │ │ ├── PolicyNew.tsx
│ │ │ ├── PolicyRule.tsx
│ │ │ ├── Pool.tsx
│ │ │ ├── PoolDetailed.tsx
│ │ │ ├── PoolNew.tsx
│ │ │ ├── Pools.tsx
│ │ │ ├── PoolsFilter.tsx
│ │ │ ├── PoolsPage.tsx
│ │ │ ├── Relations.tsx
│ │ │ ├── RouterLink.tsx
│ │ │ ├── RouterRedirect.tsx
│ │ │ ├── RouterRoute.tsx
│ │ │ ├── RouterRoutes.tsx
│ │ │ ├── SearchInput.tsx
│ │ │ ├── Secret.tsx
│ │ │ ├── SecretDetailed.tsx
│ │ │ ├── SecretNew.tsx
│ │ │ ├── Secrets.tsx
│ │ │ ├── SecretsFilter.tsx
│ │ │ ├── SecretsPage.tsx
│ │ │ ├── Session.tsx
│ │ │ ├── Sessions.tsx
│ │ │ ├── Settings.tsx
│ │ │ ├── SettingsProvider.tsx
│ │ │ ├── SettingsSecondaryProvider.tsx
│ │ │ ├── Shape.tsx
│ │ │ ├── ShapeDetailed.tsx
│ │ │ ├── ShapeNew.tsx
│ │ │ ├── Shapes.tsx
│ │ │ ├── ShapesFilter.tsx
│ │ │ ├── ShapesPage.tsx
│ │ │ ├── Storage.tsx
│ │ │ ├── StorageDetailed.tsx
│ │ │ ├── StorageNew.tsx
│ │ │ ├── Storages.tsx
│ │ │ ├── StoragesFilter.tsx
│ │ │ ├── StoragesPage.tsx
│ │ │ ├── Subscription.tsx
│ │ │ ├── Switch.tsx
│ │ │ ├── SwitchNull.tsx
│ │ │ ├── User.tsx
│ │ │ ├── UserDetailed.tsx
│ │ │ ├── Users.tsx
│ │ │ ├── UsersFilter.tsx
│ │ │ ├── UsersPage.tsx
│ │ │ ├── Vpc.tsx
│ │ │ ├── VpcArp.tsx
│ │ │ ├── VpcDetailed.tsx
│ │ │ ├── VpcLinkUri.tsx
│ │ │ ├── VpcMap.tsx
│ │ │ ├── VpcNew.tsx
│ │ │ ├── VpcRoute.tsx
│ │ │ ├── VpcSubnet.tsx
│ │ │ ├── Vpcs.tsx
│ │ │ ├── VpcsFilter.tsx
│ │ │ ├── VpcsPage.tsx
│ │ │ ├── Zone.tsx
│ │ │ ├── ZoneDetailed.tsx
│ │ │ ├── ZoneNew.tsx
│ │ │ ├── Zones.tsx
│ │ │ ├── ZonesFilter.tsx
│ │ │ └── ZonesPage.tsx
│ │ ├── dispatcher/
│ │ │ ├── Base.ts
│ │ │ ├── Dispatcher.ts
│ │ │ ├── EventDispatcher.ts
│ │ │ └── LoadingDispatcher.ts
│ │ ├── stores/
│ │ │ ├── AlertsStore.ts
│ │ │ ├── AuditsStore.ts
│ │ │ ├── AuthoritiesStore.ts
│ │ │ ├── BalancersStore.ts
│ │ │ ├── BlocksStore.ts
│ │ │ ├── CertificatesStore.ts
│ │ │ ├── CompletionStore.ts
│ │ │ ├── DatacentersStore.ts
│ │ │ ├── DevicesStore.ts
│ │ │ ├── DisksStore.ts
│ │ │ ├── DomainsNameStore.ts
│ │ │ ├── DomainsStore.ts
│ │ │ ├── FirewallsStore.ts
│ │ │ ├── ImagesDatacenterStore.ts
│ │ │ ├── ImagesStore.ts
│ │ │ ├── InstancesNodeStore.ts
│ │ │ ├── InstancesStore.ts
│ │ │ ├── LoadingStore.ts
│ │ │ ├── LogsStore.ts
│ │ │ ├── NodesStore.ts
│ │ │ ├── NodesZoneStore.ts
│ │ │ ├── OrganizationsStore.ts
│ │ │ ├── PlansStore.ts
│ │ │ ├── PodsStore.ts
│ │ │ ├── PodsUnitStore.ts
│ │ │ ├── PoliciesStore.ts
│ │ │ ├── PoolsStore.ts
│ │ │ ├── SecretsStore.ts
│ │ │ ├── SessionsStore.ts
│ │ │ ├── SettingsStore.ts
│ │ │ ├── ShapesStore.ts
│ │ │ ├── StoragesStore.ts
│ │ │ ├── SubscriptionStore.ts
│ │ │ ├── UserStore.ts
│ │ │ ├── UsersStore.ts
│ │ │ ├── VpcsNameStore.ts
│ │ │ ├── VpcsStore.ts
│ │ │ └── ZonesStore.ts
│ │ ├── types/
│ │ │ ├── AgentTypes.ts
│ │ │ ├── AlertTypes.ts
│ │ │ ├── AuditTypes.ts
│ │ │ ├── AuthorityTypes.ts
│ │ │ ├── BalancerTypes.ts
│ │ │ ├── BlockTypes.ts
│ │ │ ├── CertificateTypes.ts
│ │ │ ├── CompletionTypes.ts
│ │ │ ├── DatacenterTypes.ts
│ │ │ ├── DeviceTypes.ts
│ │ │ ├── DiskTypes.ts
│ │ │ ├── DomainTypes.ts
│ │ │ ├── FirewallTypes.ts
│ │ │ ├── GlobalTypes.ts
│ │ │ ├── ImageTypes.ts
│ │ │ ├── InstanceTypes.ts
│ │ │ ├── LoadingTypes.ts
│ │ │ ├── LogTypes.ts
│ │ │ ├── NodeTypes.ts
│ │ │ ├── OrganizationTypes.ts
│ │ │ ├── PlanTypes.ts
│ │ │ ├── PodTypes.ts
│ │ │ ├── PolicyTypes.ts
│ │ │ ├── PoolTypes.ts
│ │ │ ├── RelationTypes.ts
│ │ │ ├── RouterTypes.ts
│ │ │ ├── SecretTypes.ts
│ │ │ ├── SessionTypes.ts
│ │ │ ├── SettingsTypes.ts
│ │ │ ├── ShapeTypes.ts
│ │ │ ├── StorageTypes.ts
│ │ │ ├── SubscriptionTypes.ts
│ │ │ ├── UserTypes.ts
│ │ │ ├── VpcTypes.ts
│ │ │ └── ZoneTypes.ts
│ │ └── utils/
│ │ ├── AgentUtils.ts
│ │ └── MiscUtils.tsx
│ ├── build.sh
│ ├── build_remote.sh
│ ├── dist/
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── static/
│ │ │ ├── blueprint-datetime2.css
│ │ │ ├── blueprint-icons.css
│ │ │ ├── blueprint3.css
│ │ │ ├── blueprint5.css
│ │ │ ├── global.css
│ │ │ └── normalize.css
│ │ └── uindex.html
│ ├── dist-dev/
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── static/
│ │ │ ├── blueprint-datetime2.css
│ │ │ ├── blueprint-icons.css
│ │ │ ├── blueprint3.css
│ │ │ ├── blueprint5.css
│ │ │ ├── global.css
│ │ │ └── normalize.css
│ │ └── uindex.html
│ ├── index.html
│ ├── index_dist.html
│ ├── login.html
│ ├── package.json
│ ├── styles/
│ │ ├── blueprint.css
│ │ └── global.css
│ ├── tsconfig.json
│ ├── uindex.html
│ ├── uindex_dist.html
│ ├── webpack.config.js
│ └── webpack.dev.config.js
└── zone/
├── constants.go
├── utils.go
└── zone.go
Showing preview only (519K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6772 symbols across 982 files)
FILE: acme/acme.go
function Generate (line 26) | func Generate(db *database.Database, cert *certificate.Certificate) (
function create (line 376) | func create(db *database.Database, cert *certificate.Certificate,
function Renew (line 441) | func Renew(db *database.Database, cert *certificate.Certificate, force b...
function RenewBackground (line 461) | func RenewBackground(cert *certificate.Certificate, force bool) {
FILE: acme/challenge.go
type Challenge (line 11) | type Challenge struct
method Insert (line 17) | func (c *Challenge) Insert(db *database.Database) (err error) {
method Remove (line 29) | func (c *Challenge) Remove(db *database.Database) (err error) {
type ChallengeMsg (line 48) | type ChallengeMsg struct
method Publish (line 53) | func (c *ChallengeMsg) Publish(db *database.Database) (err error) {
FILE: acme/constants.go
constant AcmeDirectory (line 4) | AcmeDirectory = "https://acme-v02.api.letsencrypt.org/directory"
constant AcmePath (line 5) | AcmePath = "/.well-known/acme-challenge/"
FILE: acme/utils.go
function revoke (line 23) | func revoke(client *acme.Client, authzUrls []string) {
function ParsePath (line 43) | func ParsePath(path string) string {
function DnsTxtWait (line 51) | func DnsTxtWait(domain, val string) (found bool, err error) {
function GetChallenge (line 79) | func GetChallenge(token string) (challenge *Challenge, err error) {
function newRsaCsr (line 94) | func newRsaCsr(domains []string) (csr []byte, keyPem []byte, err error) {
function newEcCsr (line 133) | func newEcCsr(domains []string) (csr []byte, keyPem []byte, err error) {
FILE: advisory/advisory.go
type Advisory (line 18) | type Advisory struct
method Validate (line 35) | func (a *Advisory) Validate(db *database.Database) (
method IsFresh (line 151) | func (a *Advisory) IsFresh() bool {
method Commit (line 172) | func (a *Advisory) Commit(db *database.Database) (err error) {
FILE: advisory/constants.go
constant None (line 10) | None = "none"
constant Low (line 11) | Low = "low"
constant Medium (line 12) | Medium = "medium"
constant High (line 13) | High = "high"
constant Critical (line 14) | Critical = "critical"
constant Network (line 15) | Network = "network"
constant Adjacent (line 16) | Adjacent = "adjacent"
constant Local (line 17) | Local = "local"
constant Physical (line 18) | Physical = "physical"
constant Required (line 19) | Required = "required"
constant Unchanged (line 20) | Unchanged = "unchanged"
constant Changed (line 21) | Changed = "changed"
constant Analyzed (line 23) | Analyzed = "analyzed"
constant AwaitingAnalysis (line 24) | AwaitingAnalysis = "awaiting_analysis"
constant Rejected (line 25) | Rejected = "rejected"
constant Undergoing (line 26) | Undergoing = "undergoing_analysis"
constant Modified (line 27) | Modified = "modified"
constant Deferred (line 28) | Deferred = "deferred"
constant Pending (line 29) | Pending = "pending"
constant nvdApi (line 31) | nvdApi = "https://services.nvd.nist.gov/rest/json/cves/2.0"
FILE: advisory/utils.go
type nvdCvssData (line 20) | type nvdCvssData struct
type nvdCvssMetric (line 34) | type nvdCvssMetric struct
type nvdMetrics (line 39) | type nvdMetrics struct
type nvdDescription (line 43) | type nvdDescription struct
type nvdCve (line 48) | type nvdCve struct
type nvdVulnerability (line 55) | type nvdVulnerability struct
type nvdResponse (line 59) | type nvdResponse struct
function normalizeStatus (line 64) | func normalizeStatus(status string) string {
function normalizeValue (line 83) | func normalizeValue(val string) string {
function getOne (line 114) | func getOne(db *database.Database, query *bson.M) (adv *Advisory, err er...
function getOneNvd (line 127) | func getOneNvd(db *database.Database, cveId string) (
function GetOneLimit (line 238) | func GetOneLimit(db *database.Database, cveId string) (
function GetOne (line 276) | func GetOne(db *database.Database, cveId string) (adv *Advisory, err err...
function Remove (line 300) | func Remove(db *database.Database, advId bson.ObjectID) (err error) {
FILE: agent/agent.go
constant help (line 23) | help = `
function main (line 36) | func main() {
function daemonFork (line 411) | func daemonFork() (err error) {
FILE: agent/constants/constants.go
constant Version (line 4) | Version = "1.0.3248.95"
constant ImdsConfPath (line 5) | ImdsConfPath = "/etc/pritunl-imds.json"
constant ImdsLogPath (line 6) | ImdsLogPath = "/var/log/pritunl-imds.log"
FILE: agent/imds/imds.go
type Imds (line 37) | type Imds struct
method NewRequest (line 50) | func (m *Imds) NewRequest(method, pth string, data interface{}) (
method Get (line 89) | func (m *Imds) Get(query string) (val string, err error) {
method SyncReady (line 147) | func (m *Imds) SyncReady(timeout time.Duration) (err error) {
method Sync (line 180) | func (m *Imds) Sync() (ready bool, err error) {
method SetInitialized (line 330) | func (m *Imds) SetInitialized() {
method RunSync (line 337) | func (m *Imds) RunSync(fast bool) {
method SyncStatus (line 391) | func (m *Imds) SyncStatus(status string) (err error) {
method Wait (line 405) | func (m *Imds) Wait() (err error) {
method Init (line 411) | func (m *Imds) Init(eng *engine.Engine) (err error) {
method OpenLog (line 430) | func (m *Imds) OpenLog() (err error) {
method Close (line 441) | func (m *Imds) Close() {
type SyncResp (line 141) | type SyncResp struct
FILE: agent/imds/journal.go
type Journal (line 8) | type Journal struct
method Open (line 17) | func (j *Journal) Open() (err error) {
method Close (line 34) | func (j *Journal) Close() {
FILE: agent/imds/sync.go
type StateData (line 18) | type StateData struct
method GetState (line 22) | func (m *Imds) GetState(curHash uint32) (data *StateData, err error) {
function SetStatus (line 63) | func SetStatus(status string) {
FILE: agent/imds/utils.go
function GetState (line 12) | func GetState() string {
function SetState (line 28) | func SetState(state string) (err error) {
FILE: agent/logging/file.go
type File (line 17) | type File struct
method GetOutput (line 25) | func (f *File) GetOutput() (entries []*types.Entry) {
method followJournal (line 36) | func (f *File) followJournal() (err error) {
method Open (line 111) | func (f *File) Open() (err error) {
method Close (line 163) | func (f *File) Close() (err error) {
function NewFile (line 189) | func NewFile(path string) *File {
FILE: agent/logging/handler.go
type Handler (line 7) | type Handler interface
FILE: agent/logging/logging.go
constant maxCapacity (line 16) | maxCapacity = 128 * 1024
type Redirect (line 18) | type Redirect struct
method GetOutput (line 30) | func (r *Redirect) GetOutput() (entries []*types.Entry) {
method handleOutput (line 41) | func (r *Redirect) handleOutput(reader *os.File, level int32) {
method Open (line 67) | func (r *Redirect) Open() (err error) {
method Close (line 110) | func (r *Redirect) Close() (err error) {
FILE: agent/logging/systemd.go
type Systemd (line 20) | type Systemd struct
method GetOutput (line 34) | func (s *Systemd) GetOutput() (entries []*types.Entry) {
method followJournal (line 45) | func (s *Systemd) followJournal() (err error) {
method Open (line 173) | func (s *Systemd) Open() (err error) {
method Close (line 225) | func (s *Systemd) Close() (err error) {
type journalEntry (line 28) | type journalEntry struct
function NewSystemd (line 251) | func NewSystemd(unit string) *Systemd {
FILE: agent/utils/sanitize.go
type fileOp (line 10) | type fileOp struct
type findOp (line 16) | type findOp struct
function Sanitize (line 22) | func Sanitize() (err error) {
function SanitizeImds (line 116) | func SanitizeImds() (err error) {
FILE: agent/utils/sys.go
function Read (line 12) | func Read(path string) (data string, err error) {
function DelayExit (line 25) | func DelayExit(code int, delay time.Duration) {
FILE: aggregate/block.go
type BlockPipe (line 13) | type BlockPipe struct
type BlocksPipe (line 18) | type BlocksPipe struct
type BlockAggregate (line 23) | type BlockAggregate struct
function GetBlockPaged (line 29) | func GetBlockPaged(db *database.Database, query *bson.M, page,
FILE: aggregate/deployment.go
type DeploymentPipe (line 19) | type DeploymentPipe struct
type Deployment (line 28) | type Deployment struct
function GetDeployments (line 69) | func GetDeployments(db *database.Database, unt *unit.Unit) (
FILE: aggregate/disk.go
type DiskPipe (line 14) | type DiskPipe struct
type DisksPipe (line 19) | type DisksPipe struct
type DiskBackup (line 24) | type DiskBackup struct
type DiskAggregate (line 29) | type DiskAggregate struct
function GetDiskPaged (line 34) | func GetDiskPaged(db *database.Database, query *bson.M, page,
FILE: aggregate/domain.go
type Domain (line 13) | type Domain struct
type DomainsPipe (line 18) | type DomainsPipe struct
function GetDomainPaged (line 23) | func GetDomainPaged(db *database.Database, query *bson.M, page,
FILE: aggregate/instance.go
type InstancePipe (line 27) | type InstancePipe struct
type InstancesPipe (line 34) | type InstancesPipe struct
type InstanceInfo (line 39) | type InstanceInfo struct
type InstanceAggregate (line 54) | type InstanceAggregate struct
function GetInstancePaged (line 59) | func GetInstancePaged(db *database.Database, query *bson.M, page,
FILE: aggregate/pod.go
function sortUnits (line 15) | func sortUnits(units []*unit.Unit) {
type PodPipe (line 21) | type PodPipe struct
type Metadata (line 26) | type Metadata struct
type PodsPipe (line 30) | type PodsPipe struct
type PodAggregate (line 35) | type PodAggregate struct
function GetPod (line 40) | func GetPod(db *database.Database, usrId bson.ObjectID, query *bson.M) (
function GetPodsPaged (line 96) | func GetPodsPaged(db *database.Database, usrId bson.ObjectID,
FILE: aggregate/shape.go
type ShapePipe (line 14) | type ShapePipe struct
type ShapesPipe (line 19) | type ShapesPipe struct
function GetShapePaged (line 24) | func GetShapePaged(db *database.Database, query *bson.M, page,
FILE: ahandlers/alert.go
type alertData (line 21) | type alertData struct
type alertsData (line 35) | type alertsData struct
function alertPut (line 40) | func alertPut(c *gin.Context) {
function alertPost (line 115) | func alertPost(c *gin.Context) {
function alertDelete (line 171) | func alertDelete(c *gin.Context) {
function alertsDelete (line 195) | func alertsDelete(c *gin.Context) {
function alertGet (line 220) | func alertGet(c *gin.Context) {
function alertsGet (line 244) | func alertsGet(c *gin.Context) {
FILE: ahandlers/audit.go
type auditsData (line 13) | type auditsData struct
function auditsGet (line 18) | func auditsGet(c *gin.Context) {
FILE: ahandlers/auth.go
function authStateGet (line 25) | func authStateGet(c *gin.Context) {
type authData (line 40) | type authData struct
function authSessionPost (line 45) | func authSessionPost(c *gin.Context) {
type secondaryData (line 193) | type secondaryData struct
function authSecondaryPost (line 199) | func authSecondaryPost(c *gin.Context) {
function logoutGet (line 362) | func logoutGet(c *gin.Context) {
function authRequestGet (line 392) | func authRequestGet(c *gin.Context) {
function authCallbackGet (line 396) | func authCallbackGet(c *gin.Context) {
function authWanRegisterGet (line 564) | func authWanRegisterGet(c *gin.Context) {
type authWanRegisterData (line 644) | type authWanRegisterData struct
function authWanRegisterPost (line 649) | func authWanRegisterPost(c *gin.Context) {
function authWanRequestGet (line 789) | func authWanRequestGet(c *gin.Context) {
type authWanRespondData (line 844) | type authWanRespondData struct
function authWanRespondPost (line 848) | func authWanRespondPost(c *gin.Context) {
FILE: ahandlers/authority.go
type authorityData (line 21) | type authorityData struct
type authoritiesData (line 33) | type authoritiesData struct
function authorityPut (line 38) | func authorityPut(c *gin.Context) {
function authorityPost (line 109) | func authorityPost(c *gin.Context) {
function authorityDelete (line 161) | func authorityDelete(c *gin.Context) {
function authoritiesDelete (line 185) | func authoritiesDelete(c *gin.Context) {
function authorityGet (line 213) | func authorityGet(c *gin.Context) {
function authoritiesGet (line 237) | func authoritiesGet(c *gin.Context) {
FILE: ahandlers/balancer.go
type balancerData (line 21) | type balancerData struct
type balancersData (line 36) | type balancersData struct
function balancerPut (line 41) | func balancerPut(c *gin.Context) {
function balancerPost (line 120) | func balancerPost(c *gin.Context) {
function balancerDelete (line 177) | func balancerDelete(c *gin.Context) {
function balancersDelete (line 201) | func balancersDelete(c *gin.Context) {
function balancerGet (line 229) | func balancerGet(c *gin.Context) {
function balancersGet (line 255) | func balancersGet(c *gin.Context) {
FILE: ahandlers/block.go
type blockData (line 23) | type blockData struct
type blocksData (line 37) | type blocksData struct
function blockPut (line 42) | func blockPut(c *gin.Context) {
function blockPost (line 115) | func blockPost(c *gin.Context) {
function blockDelete (line 169) | func blockDelete(c *gin.Context) {
function blocksDelete (line 204) | func blocksDelete(c *gin.Context) {
function blockGet (line 243) | func blockGet(c *gin.Context) {
function blocksGet (line 267) | func blocksGet(c *gin.Context) {
FILE: ahandlers/certificate.go
type certificateData (line 23) | type certificateData struct
type certificatesData (line 38) | type certificatesData struct
function certificatePut (line 43) | func certificatePut(c *gin.Context) {
function certificatePost (line 126) | func certificatePost(c *gin.Context) {
function certificateDelete (line 187) | func certificateDelete(c *gin.Context) {
function certificatesDelete (line 222) | func certificatesDelete(c *gin.Context) {
function certificateGet (line 261) | func certificateGet(c *gin.Context) {
function certificatesGet (line 290) | func certificatesGet(c *gin.Context) {
FILE: ahandlers/check.go
function checkGet (line 7) | func checkGet(c *gin.Context) {
FILE: ahandlers/completion.go
function completionGet (line 28) | func completionGet(c *gin.Context) {
FILE: ahandlers/csrf.go
type csrfData (line 12) | type csrfData struct
function csrfGet (line 19) | func csrfGet(c *gin.Context) {
FILE: ahandlers/datacenter.go
type datacenterData (line 22) | type datacenterData struct
type datacentersData (line 37) | type datacentersData struct
function datacenterPut (line 42) | func datacenterPut(c *gin.Context) {
function datacenterPost (line 119) | func datacenterPost(c *gin.Context) {
function datacenterDelete (line 174) | func datacenterDelete(c *gin.Context) {
function datacentersDelete (line 209) | func datacentersDelete(c *gin.Context) {
function datacenterGet (line 248) | func datacenterGet(c *gin.Context) {
function datacentersGet (line 272) | func datacentersGet(c *gin.Context) {
FILE: ahandlers/devices.go
type deviceData (line 21) | type deviceData struct
function devicePut (line 29) | func devicePut(c *gin.Context) {
function devicePost (line 86) | func devicePost(c *gin.Context) {
function deviceDelete (line 130) | func deviceDelete(c *gin.Context) {
function devicesGet (line 154) | func devicesGet(c *gin.Context) {
function deviceAlertPost (line 172) | func deviceAlertPost(c *gin.Context) {
function deviceMethodPost (line 217) | func deviceMethodPost(c *gin.Context) {
type devicesWanRegisterRespData (line 230) | type devicesWanRegisterRespData struct
function deviceWanRegisterGet (line 235) | func deviceWanRegisterGet(c *gin.Context) {
type devicesWanRegisterData (line 284) | type devicesWanRegisterData struct
function deviceWanRegisterPost (line 289) | func deviceWanRegisterPost(c *gin.Context) {
FILE: ahandlers/disk.go
type diskData (line 27) | type diskData struct
type disksMultiData (line 49) | type disksMultiData struct
type disksData (line 54) | type disksData struct
function diskPut (line 59) | func diskPut(c *gin.Context) {
function diskPost (line 174) | func diskPost(c *gin.Context) {
function disksPut (line 285) | func disksPut(c *gin.Context) {
function diskDelete (line 327) | func diskDelete(c *gin.Context) {
function disksDelete (line 386) | func disksDelete(c *gin.Context) {
function diskGet (line 425) | func diskGet(c *gin.Context) {
function disksGet (line 449) | func disksGet(c *gin.Context) {
FILE: ahandlers/domain.go
type domainData (line 20) | type domainData struct
type domainsData (line 31) | type domainsData struct
function domainPut (line 36) | func domainPut(c *gin.Context) {
function domainPost (line 114) | func domainPost(c *gin.Context) {
function domainDelete (line 161) | func domainDelete(c *gin.Context) {
function domainsDelete (line 185) | func domainsDelete(c *gin.Context) {
function domainGet (line 210) | func domainGet(c *gin.Context) {
function domainsGet (line 241) | func domainsGet(c *gin.Context) {
FILE: ahandlers/event.go
constant writeTimeout (line 19) | writeTimeout = 10 * time.Second
constant pingInterval (line 20) | pingInterval = 30 * time.Second
constant pingWait (line 21) | pingWait = 40 * time.Second
function eventGet (line 24) | func eventGet(c *gin.Context) {
FILE: ahandlers/firewall.go
type firewallData (line 20) | type firewallData struct
type firewallsData (line 29) | type firewallsData struct
function firewallPut (line 34) | func firewallPut(c *gin.Context) {
function firewallPost (line 96) | func firewallPost(c *gin.Context) {
function firewallDelete (line 142) | func firewallDelete(c *gin.Context) {
function firewallsDelete (line 177) | func firewallsDelete(c *gin.Context) {
function firewallGet (line 213) | func firewallGet(c *gin.Context) {
function firewallsGet (line 237) | func firewallsGet(c *gin.Context) {
FILE: ahandlers/handlers.go
function Register (line 19) | func Register(engine *gin.Engine) {
function init (line 284) | func init() {
FILE: ahandlers/image.go
type imageData (line 21) | type imageData struct
type imagesData (line 28) | type imagesData struct
function imagePut (line 33) | func imagePut(c *gin.Context) {
function imageDelete (line 91) | func imageDelete(c *gin.Context) {
function imagesDelete (line 116) | func imagesDelete(c *gin.Context) {
function imageGet (line 142) | func imageGet(c *gin.Context) {
function imagesGet (line 162) | func imagesGet(c *gin.Context) {
FILE: ahandlers/instance.go
type instanceData (line 34) | type instanceData struct
type instanceMultiData (line 79) | type instanceMultiData struct
type instancesData (line 84) | type instancesData struct
function instancePut (line 89) | func instancePut(c *gin.Context) {
function instancePost (line 235) | func instancePost(c *gin.Context) {
function instancesPut (line 435) | func instancesPut(c *gin.Context) {
function instanceDelete (line 478) | func instanceDelete(c *gin.Context) {
function instancesDelete (line 517) | func instancesDelete(c *gin.Context) {
function instanceGet (line 553) | func instanceGet(c *gin.Context) {
function instancesGet (line 598) | func instancesGet(c *gin.Context) {
function instanceVncGet (line 767) | func instanceVncGet(c *gin.Context) {
FILE: ahandlers/license.go
type licenseData (line 12) | type licenseData struct
function licensePut (line 16) | func licensePut(c *gin.Context) {
FILE: ahandlers/log.go
type logsData (line 17) | type logsData struct
function logGet (line 22) | func logGet(c *gin.Context) {
function logsGet (line 45) | func logsGet(c *gin.Context) {
FILE: ahandlers/node.go
type nodeData (line 30) | type nodeData struct
type nodesData (line 80) | type nodesData struct
type nodeInitData (line 85) | type nodeInitData struct
function nodePut (line 96) | func nodePut(c *gin.Context) {
function nodeOperationPut (line 278) | func nodeOperationPut(c *gin.Context) {
function nodeInitPost (line 327) | func nodeInitPost(c *gin.Context) {
function nodeDelete (line 584) | func nodeDelete(c *gin.Context) {
function nodeGet (line 619) | func nodeGet(c *gin.Context) {
function nodesGet (line 644) | func nodesGet(c *gin.Context) {
FILE: ahandlers/organization.go
type organizationData (line 22) | type organizationData struct
type organizationsData (line 29) | type organizationsData struct
function organizationPut (line 34) | func organizationPut(c *gin.Context) {
function organizationPost (line 92) | func organizationPost(c *gin.Context) {
function organizationDelete (line 153) | func organizationDelete(c *gin.Context) {
function organizationGet (line 188) | func organizationGet(c *gin.Context) {
function organizationsGet (line 212) | func organizationsGet(c *gin.Context) {
FILE: ahandlers/plan.go
type planData (line 19) | type planData struct
type plansData (line 27) | type plansData struct
function planPut (line 32) | func planPut(c *gin.Context) {
function planPost (line 97) | func planPost(c *gin.Context) {
function planDelete (line 147) | func planDelete(c *gin.Context) {
function plansDelete (line 171) | func plansDelete(c *gin.Context) {
function planGet (line 196) | func planGet(c *gin.Context) {
function plansGet (line 220) | func plansGet(c *gin.Context) {
FILE: ahandlers/pod.go
type podData (line 29) | type podData struct
type podsData (line 40) | type podsData struct
type podsDeployData (line 45) | type podsDeployData struct
type deploymentData (line 50) | type deploymentData struct
type specsData (line 55) | type specsData struct
function podPut (line 60) | func podPut(c *gin.Context) {
function podDraftsPut (line 142) | func podDraftsPut(c *gin.Context) {
function podDeployPut (line 181) | func podDeployPut(c *gin.Context) {
function podPost (line 245) | func podPost(c *gin.Context) {
function podDelete (line 305) | func podDelete(c *gin.Context) {
function podsDelete (line 341) | func podsDelete(c *gin.Context) {
function podGet (line 381) | func podGet(c *gin.Context) {
function podsGet (line 418) | func podsGet(c *gin.Context) {
type PodUnit (line 519) | type PodUnit struct
function podUnitGet (line 526) | func podUnitGet(c *gin.Context) {
function podUnitDeploymentsPut (line 598) | func podUnitDeploymentsPut(c *gin.Context) {
function podUnitDeploymentPost (line 678) | func podUnitDeploymentPost(c *gin.Context) {
function podUnitDeploymentPut (line 725) | func podUnitDeploymentPut(c *gin.Context) {
function podUnitDeploymentLogGet (line 788) | func podUnitDeploymentLogGet(c *gin.Context) {
function podUnitSpecsGet (line 848) | func podUnitSpecsGet(c *gin.Context) {
function podUnitSpecGet (line 903) | func podUnitSpecGet(c *gin.Context) {
FILE: ahandlers/policy.go
type policyData (line 22) | type policyData struct
type policiesData (line 38) | type policiesData struct
function policyPut (line 43) | func policyPut(c *gin.Context) {
function policyPost (line 113) | func policyPost(c *gin.Context) {
function policyDelete (line 163) | func policyDelete(c *gin.Context) {
function policiesDelete (line 198) | func policiesDelete(c *gin.Context) {
function policyGet (line 237) | func policyGet(c *gin.Context) {
function policiesGet (line 261) | func policiesGet(c *gin.Context) {
FILE: ahandlers/pool.go
type poolData (line 22) | type poolData struct
type poolsData (line 32) | type poolsData struct
function poolPut (line 37) | func poolPut(c *gin.Context) {
function poolPost (line 97) | func poolPost(c *gin.Context) {
function poolDelete (line 150) | func poolDelete(c *gin.Context) {
function poolsDelete (line 174) | func poolsDelete(c *gin.Context) {
function poolGet (line 199) | func poolGet(c *gin.Context) {
function poolsGet (line 223) | func poolsGet(c *gin.Context) {
FILE: ahandlers/relations.go
type relationsData (line 11) | type relationsData struct
function relationsGet (line 17) | func relationsGet(c *gin.Context) {
FILE: ahandlers/secret.go
type secretData (line 22) | type secretData struct
type secretsData (line 34) | type secretsData struct
function secretPut (line 39) | func secretPut(c *gin.Context) {
function secretPost (line 112) | func secretPost(c *gin.Context) {
function secretDelete (line 164) | func secretDelete(c *gin.Context) {
function secretsDelete (line 199) | func secretsDelete(c *gin.Context) {
function secretGet (line 238) | func secretGet(c *gin.Context) {
function secretsGet (line 267) | func secretsGet(c *gin.Context) {
FILE: ahandlers/session.go
function sessionsGet (line 15) | func sessionsGet(c *gin.Context) {
function sessionDelete (line 41) | func sessionDelete(c *gin.Context) {
FILE: ahandlers/settings.go
type settingsData (line 13) | type settingsData struct
function getSettingsData (line 31) | func getSettingsData() *settingsData {
function settingsGet (line 50) | func settingsGet(c *gin.Context) {
function settingsPut (line 55) | func settingsPut(c *gin.Context) {
FILE: ahandlers/shape.go
type shapeData (line 21) | type shapeData struct
type shapesData (line 36) | type shapesData struct
function shapePut (line 41) | func shapePut(c *gin.Context) {
function shapePost (line 115) | func shapePost(c *gin.Context) {
function shapeDelete (line 166) | func shapeDelete(c *gin.Context) {
function shapesDelete (line 201) | func shapesDelete(c *gin.Context) {
function shapeGet (line 237) | func shapeGet(c *gin.Context) {
function shapesGet (line 261) | func shapesGet(c *gin.Context) {
FILE: ahandlers/static.go
function staticPath (line 16) | func staticPath(c *gin.Context, pth string, cache bool) {
function staticIndexGet (line 43) | func staticIndexGet(c *gin.Context) {
function staticLoginGet (line 59) | func staticLoginGet(c *gin.Context) {
function staticLogoGet (line 63) | func staticLogoGet(c *gin.Context) {
function staticGet (line 67) | func staticGet(c *gin.Context) {
function staticTestingGet (line 71) | func staticTestingGet(c *gin.Context) {
FILE: ahandlers/storage.go
type storageData (line 23) | type storageData struct
type storagesData (line 35) | type storagesData struct
function storagePut (line 40) | func storagePut(c *gin.Context) {
function storagePost (line 122) | func storagePost(c *gin.Context) {
function storageDelete (line 185) | func storageDelete(c *gin.Context) {
function storagesDelete (line 209) | func storagesDelete(c *gin.Context) {
function storageGet (line 237) | func storageGet(c *gin.Context) {
function storagesGet (line 270) | func storagesGet(c *gin.Context) {
FILE: ahandlers/subscription.go
type subscriptionPostData (line 16) | type subscriptionPostData struct
function subscriptionGet (line 20) | func subscriptionGet(c *gin.Context) {
function subscriptionUpdateGet (line 28) | func subscriptionUpdateGet(c *gin.Context) {
function subscriptionPost (line 47) | func subscriptionPost(c *gin.Context) {
FILE: ahandlers/theme.go
type themeData (line 12) | type themeData struct
function themePut (line 17) | func themePut(c *gin.Context) {
FILE: ahandlers/user.go
type userData (line 20) | type userData struct
type usersData (line 34) | type usersData struct
function userGet (line 39) | func userGet(c *gin.Context) {
function userPut (line 66) | func userPut(c *gin.Context) {
function userPost (line 184) | func userPost(c *gin.Context) {
function usersGet (line 247) | func usersGet(c *gin.Context) {
function usersDelete (line 360) | func usersDelete(c *gin.Context) {
FILE: ahandlers/vpc.go
type vpcData (line 22) | type vpcData struct
type vpcsData (line 36) | type vpcsData struct
function vpcPut (line 41) | func vpcPut(c *gin.Context) {
function vpcPost (line 122) | func vpcPost(c *gin.Context) {
function vpcDelete (line 180) | func vpcDelete(c *gin.Context) {
function vpcsDelete (line 215) | func vpcsDelete(c *gin.Context) {
function vpcGet (line 251) | func vpcGet(c *gin.Context) {
function vpcRoutesGet (line 277) | func vpcRoutesGet(c *gin.Context) {
function vpcRoutesPut (line 301) | func vpcRoutesPut(c *gin.Context) {
function vpcsGet (line 357) | func vpcsGet(c *gin.Context) {
FILE: ahandlers/zone.go
type zoneData (line 22) | type zoneData struct
type zonesData (line 29) | type zonesData struct
function zonePut (line 34) | func zonePut(c *gin.Context) {
function zonePost (line 90) | func zonePost(c *gin.Context) {
function zoneDelete (line 134) | func zoneDelete(c *gin.Context) {
function zonesDelete (line 169) | func zonesDelete(c *gin.Context) {
function zoneGet (line 208) | func zoneGet(c *gin.Context) {
function zonesGet (line 232) | func zonesGet(c *gin.Context) {
FILE: alert/alert.go
type Alert (line 11) | type Alert struct
method Validate (line 25) | func (a *Alert) Validate(db *database.Database) (
method Commit (line 92) | func (a *Alert) Commit(db *database.Database) (err error) {
method CommitFields (line 103) | func (a *Alert) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 116) | func (a *Alert) Insert(db *database.Database) (err error) {
FILE: alert/constants.go
constant Low (line 4) | Low = 1
constant Medium (line 5) | Medium = 5
constant High (line 6) | High = 10
constant InstanceOffline (line 10) | InstanceOffline = "instance_offline"
FILE: alert/utils.go
function Get (line 11) | func Get(db *database.Database, alertId bson.ObjectID) (
function GetOrg (line 25) | func GetOrg(db *database.Database, orgId, alertId bson.ObjectID) (
function GetMulti (line 43) | func GetMulti(db *database.Database, alertIds []bson.ObjectID) (
function GetAll (line 83) | func GetAll(db *database.Database) (alerts []*Alert, err error) {
function GetAllPaged (line 117) | func GetAllPaged(db *database.Database, query *bson.M,
function GetRoles (line 180) | func GetRoles(db *database.Database, roles []string) (
function GetRolesMapped (line 224) | func GetRolesMapped(db *database.Database, rolesSet set.Set) (
function Remove (line 252) | func Remove(db *database.Database,
function RemoveOrg (line 268) | func RemoveOrg(db *database.Database, orgId, alertId bson.ObjectID) (
function RemoveMulti (line 290) | func RemoveMulti(db *database.Database, alertIds []bson.ObjectID) (
function RemoveMultiOrg (line 308) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: alertevent/alertevent.go
type Alert (line 14) | type Alert struct
method DocId (line 27) | func (a *Alert) DocId() string {
method Key (line 39) | func (a *Alert) Key(devc *device.Device) string {
method Lock (line 52) | func (a *Alert) Lock(db *database.Database, devc *device.Device) (
method FormattedTextMessage (line 74) | func (a *Alert) FormattedTextMessage() string {
method FormattedCallMessage (line 78) | func (a *Alert) FormattedCallMessage() string {
method Send (line 82) | func (a *Alert) Send(db *database.Database, roles []string) (err error) {
function New (line 166) | func New(roles []string, source bson.ObjectID,
FILE: alertevent/utils.go
type AlertParams (line 24) | type AlertParams struct
function SendTest (line 31) | func SendTest(db *database.Database, devc *device.Device) (
function Send (line 47) | func Send(number, message, alertType string) (
FILE: arp/arp.go
type Record (line 18) | type Record struct
type entry (line 23) | type entry struct
function GetRecords (line 31) | func GetRecords(namespace string) (records set.Set, err error) {
function BuildState (line 80) | func BuildState(instances []*instance.Instance,
function ApplyState (line 133) | func ApplyState(namespace string, oldState, newState set.Set) (
FILE: audit/audit.go
type Fields (line 13) | type Fields
type Audit (line 15) | type Audit struct
method Insert (line 24) | func (a *Audit) Insert(db *database.Database) (err error) {
FILE: audit/constants.go
constant AdminLogin (line 4) | AdminLogin = "admin_login"
constant AdminLoginFailed (line 5) | AdminLoginFailed = "admin_login_failed"
constant AdminAuthFailed (line 6) | AdminAuthFailed = "admin_auth_failed"
constant AdminLogout (line 7) | AdminLogout = "admin_logout"
constant AdminPrimaryApprove (line 8) | AdminPrimaryApprove = "admin_primary_approve"
constant AdminSecondaryApprove (line 9) | AdminSecondaryApprove = "admin_secondary_approve"
constant AdminDeviceApprove (line 10) | AdminDeviceApprove = "admin_device_approve"
constant AdminDeviceRegisterRequest (line 11) | AdminDeviceRegisterRequest = "admin_device_register_request"
constant AdminDeviceRegister (line 12) | AdminDeviceRegister = "admin_device_register"
constant ProxyLogin (line 14) | ProxyLogin = "proxy_login"
constant ProxyLoginFailed (line 15) | ProxyLoginFailed = "proxy_login_failed"
constant ProxyAuthFailed (line 16) | ProxyAuthFailed = "proxy_auth_failed"
constant ProxyLogout (line 17) | ProxyLogout = "proxy_logout"
constant ProxyPrimaryApprove (line 18) | ProxyPrimaryApprove = "proxy_primary_approve"
constant ProxySecondaryApprove (line 19) | ProxySecondaryApprove = "proxy_secondary_approve"
constant ProxyDeviceApprove (line 20) | ProxyDeviceApprove = "proxy_device_approve"
constant ProxyDeviceRegisterRequest (line 21) | ProxyDeviceRegisterRequest = "proxy_device_register_request"
constant ProxyDeviceRegister (line 22) | ProxyDeviceRegister = "proxy_device_register"
constant UserLogin (line 24) | UserLogin = "user_login"
constant UserLoginFailed (line 25) | UserLoginFailed = "user_login_failed"
constant UserAuthFailed (line 26) | UserAuthFailed = "user_auth_failed"
constant UserLogout (line 27) | UserLogout = "user_logout"
constant UserLogoutAll (line 28) | UserLogoutAll = "user_logout_all"
constant UserPrimaryApprove (line 29) | UserPrimaryApprove = "user_primary_approve"
constant UserSecondaryApprove (line 30) | UserSecondaryApprove = "user_secondary_approve"
constant UserDeviceApprove (line 31) | UserDeviceApprove = "user_device_approve"
constant UserDeviceRegisterRequest (line 32) | UserDeviceRegisterRequest = "user_device_register_request"
constant UserDeviceRegister (line 33) | UserDeviceRegister = "user_device_register"
constant UserAccountDisable (line 34) | UserAccountDisable = "user_account_disable"
constant DeviceRegister (line 36) | DeviceRegister = "device_register"
constant DeviceRegisterFailed (line 37) | DeviceRegisterFailed = "device_register_failed"
constant DuoApprove (line 38) | DuoApprove = "duo_approve"
constant DuoDeny (line 39) | DuoDeny = "duo_deny"
constant OneLoginApprove (line 40) | OneLoginApprove = "one_login_approve"
constant OneLoginDeny (line 41) | OneLoginDeny = "one_login_deny"
constant OktaApprove (line 42) | OktaApprove = "okta_approve"
constant OktaDeny (line 43) | OktaDeny = "okta_deny"
FILE: audit/utils.go
function Get (line 15) | func Get(db *database.Database, adtId string) (
function GetAll (line 29) | func GetAll(db *database.Database, userId bson.ObjectID,
function New (line 87) | func New(db *database.Database, r *http.Request,
FILE: auth/auth.go
type authData (line 17) | type authData struct
type Token (line 21) | type Token struct
method Remove (line 30) | func (t *Token) Remove(db *database.Database) (err error) {
FILE: auth/authzero.go
constant AuthZero (line 20) | AuthZero = "authzero"
function AuthZeroRequest (line 23) | func AuthZeroRequest(db *database.Database, location, query string,
type authZeroJwks (line 118) | type authZeroJwks struct
type authZeroTokenReq (line 122) | type authZeroTokenReq struct
type authZeroTokenData (line 129) | type authZeroTokenData struct
type authZeroToken (line 135) | type authZeroToken struct
type authZeroAppAuthorization (line 144) | type authZeroAppAuthorization struct
type authZeroAppMetadata (line 149) | type authZeroAppMetadata struct
type authZeroUser (line 153) | type authZeroUser struct
function authZeroGetToken (line 302) | func authZeroGetToken(provider *settings.Provider) (token string, err er...
function AuthZeroRoles (line 362) | func AuthZeroRoles(provider *settings.Provider, username string) (
function AuthZeroSync (line 451) | func AuthZeroSync(db *database.Database, usr *user.User,
FILE: auth/azure.go
constant Azure (line 20) | Azure = "azure"
function azureGetUrls (line 23) | func azureGetUrls(provider *settings.Provider) (loginUrl, graphUrl strin...
function AzureRequest (line 41) | func AzureRequest(db *database.Database, location, query string,
type azureTokenData (line 138) | type azureTokenData struct
type azureMemberData (line 144) | type azureMemberData struct
type azureUserData (line 149) | type azureUserData struct
type azureGroupData (line 155) | type azureGroupData struct
function azureGetToken (line 159) | func azureGetToken(provider *settings.Provider) (token string, err error) {
function AzureRoles (line 214) | func AzureRoles(provider *settings.Provider, username string) (
function AzureSync (line 335) | func AzureSync(provider *settings.Provider, username string) (
FILE: auth/constants.go
constant Admin (line 4) | Admin = "admin"
constant User (line 5) | User = "user"
FILE: auth/errortypes.go
type InvalidState (line 7) | type InvalidState struct
FILE: auth/google.go
constant Google (line 22) | Google = "google"
function GoogleRequest (line 25) | func GoogleRequest(db *database.Database, location, query string) (
function GoogleRoles (line 113) | func GoogleRoles(provider *settings.Provider, username string) (
function GoogleSync (line 166) | func GoogleSync(db *database.Database, usr *user.User) (
FILE: auth/handler.go
function Local (line 25) | func Local(db *database.Database, username, password string) (
function Request (line 65) | func Request(c *gin.Context, typ string) {
function Callback (line 157) | func Callback(db *database.Database, sig, query string) (
FILE: auth/jumpcloud.go
constant JumpCloud (line 19) | JumpCloud = "jumpcloud"
type jumpcloudResponse (line 22) | type jumpcloudResponse struct
type jumpcloudUser (line 27) | type jumpcloudUser struct
type jumpcloudApp (line 36) | type jumpcloudApp struct
function jumpcloudCheckApp (line 40) | func jumpcloudCheckApp(provider *settings.Provider, userId string) (
function JumpcloudSync (line 97) | func JumpcloudSync(db *database.Database, usr *user.User,
FILE: auth/saml.go
constant OneLogin (line 18) | OneLogin = "onelogin"
constant Okta (line 19) | Okta = "okta"
function SamlRequest (line 22) | func SamlRequest(db *database.Database, location, query string,
FILE: auth/state.go
type StateProvider (line 10) | type StateProvider struct
type StateProviders (line 16) | type StateProviders
method Len (line 18) | func (s StateProviders) Len() int {
method Swap (line 22) | func (s StateProviders) Swap(i, j int) {
method Less (line 26) | func (s StateProviders) Less(i, j int) bool {
type State (line 30) | type State struct
function GetState (line 34) | func GetState() (state *State) {
function GetFastAdminPath (line 73) | func GetFastAdminPath() (path string) {
function GetFastUserPath (line 106) | func GetFastUserPath() (path string) {
FILE: auth/sync.go
function SyncUser (line 12) | func SyncUser(db *database.Database, usr *user.User) (
FILE: auth/utils.go
function Get (line 16) | func Get(db *database.Database, state string) (tokn *Token, err error) {
function CookieSessionAdmin (line 28) | func CookieSessionAdmin(db *database.Database,
function CookieSessionUser (line 53) | func CookieSessionUser(db *database.Database, w http.ResponseWriter,
function CsrfCheck (line 77) | func CsrfCheck(w http.ResponseWriter, r *http.Request, domain string) bo...
FILE: authority/authority.go
type Authority (line 12) | type Authority struct
method Validate (line 24) | func (f *Authority) Validate(db *database.Database) (
method Commit (line 54) | func (f *Authority) Commit(db *database.Database) (err error) {
method CommitFields (line 65) | func (f *Authority) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 78) | func (f *Authority) Insert(db *database.Database) (err error) {
FILE: authority/constants.go
constant SshKey (line 6) | SshKey = "ssh_key"
constant SshCertificate (line 7) | SshCertificate = "ssh_certificate"
FILE: authority/utils.go
function Get (line 10) | func Get(db *database.Database, authrId bson.ObjectID) (
function GetOrg (line 24) | func GetOrg(db *database.Database, orgId, authrId bson.ObjectID) (
function GetAll (line 42) | func GetAll(db *database.Database, query *bson.M) (
function GetRoles (line 75) | func GetRoles(db *database.Database, roles []string) (
function GetMapRoles (line 115) | func GetMapRoles(db *database.Database, query *bson.M) (
function GetOrgMapRoles (line 154) | func GetOrgMapRoles(db *database.Database, orgId bson.ObjectID) (
function GetOrgRoles (line 195) | func GetOrgRoles(db *database.Database, orgId bson.ObjectID,
function GetAllNames (line 231) | func GetAllNames(db *database.Database, query *bson.M) (
function GetAllPaged (line 274) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 341) | func Remove(db *database.Database, authrId bson.ObjectID) (err error) {
function RemoveOrg (line 360) | func RemoveOrg(db *database.Database, orgId, authrId bson.ObjectID) (
function RemoveMulti (line 382) | func RemoveMulti(db *database.Database,
function RemoveMultiOrg (line 400) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: authorizer/authorizer.go
type Authorizer (line 13) | type Authorizer struct
method IsApi (line 21) | func (a *Authorizer) IsApi() bool {
method IsValid (line 25) | func (a *Authorizer) IsValid() bool {
method AddSignature (line 29) | func (a *Authorizer) AddSignature(db *database.Database,
method AddCookie (line 42) | func (a *Authorizer) AddCookie(cook *cookie.Cookie,
method Clear (line 51) | func (a *Authorizer) Clear(db *database.Database, w http.ResponseWriter,
method Remove (line 76) | func (a *Authorizer) Remove(db *database.Database) error {
method GetUser (line 84) | func (a *Authorizer) GetUser(db *database.Database) (
method GetSession (line 142) | func (a *Authorizer) GetSession() *session.Session {
method SessionId (line 146) | func (a *Authorizer) SessionId() string {
FILE: authorizer/constants.go
constant Admin (line 4) | Admin = "admin"
constant User (line 5) | User = "user"
FILE: authorizer/utils.go
function AuthorizeAdmin (line 11) | func AuthorizeAdmin(db *database.Database, w http.ResponseWriter,
function AuthorizeUser (line 56) | func AuthorizeUser(db *database.Database, w http.ResponseWriter,
function NewAdmin (line 101) | func NewAdmin() (authr *Authorizer) {
function NewUser (line 109) | func NewUser() (authr *Authorizer) {
FILE: backup/backup.go
type Backup (line 26) | type Backup struct
method backupDisk (line 33) | func (b *Backup) backupDisk(db *database.Database,
method backupDisks (line 82) | func (b *Backup) backupDisks(db *database.Database) (err error) {
method backupBackingDisks (line 161) | func (b *Backup) backupBackingDisks(db *database.Database) (err error) {
method Run (line 257) | func (b *Backup) Run() (err error) {
function New (line 297) | func New(dest string) *Backup {
FILE: balancer/balancer.go
type Domain (line 18) | type Domain struct
type Backend (line 23) | type Backend struct
type State (line 29) | type State struct
type Balancer (line 41) | type Balancer struct
method Validate (line 58) | func (b *Balancer) Validate(db *database.Database) (
method Json (line 222) | func (b *Balancer) Json() {
method Clean (line 236) | func (b *Balancer) Clean(db *database.Database) (err error) {
method CommitState (line 259) | func (b *Balancer) CommitState(db *database.Database, state *State) (
method Commit (line 278) | func (b *Balancer) Commit(db *database.Database) (err error) {
method CommitFields (line 289) | func (b *Balancer) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 331) | func (b *Balancer) Insert(db *database.Database) (err error) {
FILE: balancer/constants.go
constant Http (line 4) | Http = "http"
FILE: balancer/utils.go
function Get (line 10) | func Get(db *database.Database, balncId bson.ObjectID) (
function GetOrg (line 24) | func GetOrg(db *database.Database, orgId, balncId bson.ObjectID) (
function GetAll (line 42) | func GetAll(db *database.Database, query *bson.M) (
function GetAllPaged (line 75) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 139) | func Remove(db *database.Database, balncId bson.ObjectID) (err error) {
function RemoveOrg (line 158) | func RemoveOrg(db *database.Database, orgId, balncId bson.ObjectID) (
function RemoveMulti (line 180) | func RemoveMulti(db *database.Database, balncIds []bson.ObjectID) (
function RemoveMultiOrg (line 197) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: block/block.go
type Block (line 18) | type Block struct
method Validate (line 38) | func (b *Block) Validate(db *database.Database) (
method Contains (line 198) | func (b *Block) Contains(blckIp *BlockIp) (contains bool, err error) {
method GetGateway (line 233) | func (b *Block) GetGateway() net.IP {
method GetGateway6 (line 237) | func (b *Block) GetGateway6() net.IP {
method GetMask (line 244) | func (b *Block) GetMask() net.IPMask {
method GetGatewayCidr (line 248) | func (b *Block) GetGatewayCidr() string {
method GetNetwork (line 259) | func (b *Block) GetNetwork() (staticNet *net.IPNet, err error) {
method GetIps (line 281) | func (b *Block) GetIps(db *database.Database) (blckIpsSet set.Set, err...
method GetIpCount (line 303) | func (b *Block) GetIpCount() (count int64, err error) {
method GetIp (line 386) | func (b *Block) GetIp(db *database.Database,
method GetIp6 (line 505) | func (b *Block) GetIp6(db *database.Database,
method RemoveIp (line 575) | func (b *Block) RemoveIp(db *database.Database,
method ValidateAddresses (line 594) | func (b *Block) ValidateAddresses(db *database.Database,
method Commit (line 714) | func (b *Block) Commit(db *database.Database) (err error) {
method CommitFields (line 725) | func (b *Block) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 736) | func (b *Block) Insert(db *database.Database) (err error) {
type Completion (line 32) | type Completion struct
FILE: block/constants.go
constant External (line 4) | External = "external"
constant Host (line 5) | Host = "host"
constant NodePort (line 6) | NodePort = "node_port"
constant IPv4 (line 7) | IPv4 = "ipv4"
constant IPv6 (line 8) | IPv6 = "ipv6"
FILE: block/errortypes.go
type BlockFull (line 7) | type BlockFull struct
FILE: block/ip.go
type BlockIp (line 10) | type BlockIp struct
method GetIp (line 18) | func (b *BlockIp) GetIp() net.IP {
FILE: block/utils.go
function GetNodeBlock (line 15) | func GetNodeBlock(ndeId bson.ObjectID) (blck *Block, err error) {
function GetNodePortBlock (line 42) | func GetNodePortBlock(ndeId bson.ObjectID) (blck *Block, err error) {
function GetNodePortGateway (line 69) | func GetNodePortGateway() (gateway string, err error) {
function Get (line 84) | func Get(db *database.Database, blockId bson.ObjectID) (
function GetAll (line 98) | func GetAll(db *database.Database) (blocks []*Block, err error) {
function GetInstanceHostIp (line 132) | func GetInstanceHostIp(db *database.Database,
function GetInstanceNodePortIp (line 154) | func GetInstanceNodePortIp(db *database.Database,
function GetInstanceIp (line 176) | func GetInstanceIp(db *database.Database, instId bson.ObjectID,
function GetAllPaged (line 207) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 271) | func Remove(db *database.Database, blockId bson.ObjectID) (err error) {
function RemoveIp (line 342) | func RemoveIp(db *database.Database, blockIpId bson.ObjectID) (
function RemoveInstanceIps (line 363) | func RemoveInstanceIps(db *database.Database, instId bson.ObjectID) (
function RemoveInstanceIpsType (line 384) | func RemoveInstanceIpsType(db *database.Database,
function RemoveMulti (line 406) | func RemoveMulti(db *database.Database, blckIds []bson.ObjectID) (
FILE: bridges/bridges.go
function ClearCache (line 24) | func ClearCache() {
function GetBridges (line 29) | func GetBridges() (brdgs []ip.Interface, err error) {
function GetIpAddrs (line 112) | func GetIpAddrs(iface string) (addr string, addr6 string, err error) {
FILE: certificate/certificate.go
type Info (line 21) | type Info struct
type Certificate (line 31) | type Certificate struct
method Validate (line 55) | func (c *Certificate) Validate(db *database.Database) (
method UpdateInfo (line 143) | func (c *Certificate) UpdateInfo() (err error) {
method Commit (line 208) | func (c *Certificate) Commit(db *database.Database) (err error) {
method CommitFields (line 219) | func (c *Certificate) CommitFields(db *database.Database, fields set.S...
method Insert (line 232) | func (c *Certificate) Insert(db *database.Database) (err error) {
method Hash (line 253) | func (c *Certificate) Hash() string {
type Completion (line 48) | type Completion struct
FILE: certificate/constants.go
constant Text (line 6) | Text = "text"
constant LetsEncrypt (line 7) | LetsEncrypt = "lets_encrypt"
constant AcmeHTTP (line 9) | AcmeHTTP = "acme_http"
constant AcmeDNS (line 10) | AcmeDNS = "acme_dns"
constant AcmeAWS (line 12) | AcmeAWS = "acme_aws"
constant AcmeCloudflare (line 13) | AcmeCloudflare = "acme_cloudflare"
constant AcmeOracleCloud (line 14) | AcmeOracleCloud = "acme_oracle_cloud"
constant AcmeGoogleCloud (line 15) | AcmeGoogleCloud = "acme_google_cloud"
FILE: certificate/utils.go
function Get (line 10) | func Get(db *database.Database, certId bson.ObjectID) (
function GetOrg (line 24) | func GetOrg(db *database.Database, orgId, certId bson.ObjectID) (
function GetOne (line 42) | func GetOne(db *database.Database, query *bson.M) (cert *Certificate, er...
function GetAll (line 55) | func GetAll(db *database.Database,
function GetAllOrg (line 87) | func GetAllOrg(db *database.Database, orgId bson.ObjectID) (
function GetAllNames (line 121) | func GetAllNames(db *database.Database, query *bson.M) (
function GetAllPaged (line 160) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 224) | func Remove(db *database.Database, certId bson.ObjectID) (err error) {
function RemoveOrg (line 238) | func RemoveOrg(db *database.Database, orgId, certId bson.ObjectID) (
function RemoveMulti (line 260) | func RemoveMulti(db *database.Database, certIds []bson.ObjectID) (
function RemoveMultiOrg (line 277) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: cloud/cloud.go
type Subnet (line 3) | type Subnet struct
type Vpc (line 10) | type Vpc struct
FILE: cloud/oracle.go
function GetOracleVpcs (line 14) | func GetOracleVpcs(authPv oracle.AuthProvider) (vpcs []*Vpc, err error) {
FILE: cloudinit/cloudinit.go
constant metaDataTmpl (line 35) | metaDataTmpl = `instance-id: %s
constant userDataTmpl (line 38) | userDataTmpl = `Content-Type: multipart/mixed; boundary="%s"
constant netConfigTmpl (line 43) | netConfigTmpl = `version: 1
constant netConfigLegacyTmpl (line 62) | netConfigLegacyTmpl = `version: 1
constant netConfig2Tmpl (line 82) | netConfig2Tmpl = `version: 2
constant netMtu (line 99) | netMtu = `
constant cloudConfigTmpl (line 102) | cloudConfigTmpl = `#cloud-config
constant cloudBsdConfigTmpl (line 144) | cloudBsdConfigTmpl = `#cloud-config
constant deploymentScriptTmpl (line 181) | deploymentScriptTmpl = `#!/bin/sh
constant deploymentScriptBsdTmpl (line 192) | deploymentScriptBsdTmpl = `#!/bin/sh
type netConfigData (line 216) | type netConfigData struct
type cloudConfigData (line 233) | type cloudConfigData struct
type cloudMount (line 248) | type cloudMount struct
type imdsConfig (line 256) | type imdsConfig struct
function getUserData (line 263) | func getUserData(db *database.Database, inst *instance.Instance,
function getNetData (line 628) | func getNetData(db *database.Database, inst *instance.Instance,
function Write (line 727) | func Write(db *database.Database, inst *instance.Instance,
FILE: cloudinit/query.go
type NetworkConfig (line 13) | type NetworkConfig struct
type NetworkInterface (line 18) | type NetworkInterface struct
type Subnet (line 28) | type Subnet struct
type CloudConfig (line 34) | type CloudConfig struct
type CombinedCloudConfig (line 39) | type CombinedCloudConfig struct
type MergedSystemConfig (line 43) | type MergedSystemConfig struct
function GetCloudConfig (line 47) | func GetCloudConfig() (data *CloudConfig, err error) {
FILE: cloudinit/utils.go
type fileData (line 12) | type fileData struct
type writeFileData (line 19) | type writeFileData struct
constant writeFileTmpl (line 23) | writeFileTmpl = `{{range .Files}}
function generateWriteFiles (line 39) | func generateWriteFiles(filesData []*fileData) (output string, err error) {
FILE: cmd/backup.go
function Backup (line 13) | func Backup() (err error) {
FILE: cmd/dhcp.go
function DhcpClient (line 16) | func DhcpClient() (err error) {
function Dhcp4Server (line 25) | func Dhcp4Server() (err error) {
function Dhcp6Server (line 49) | func Dhcp6Server() (err error) {
function NdpServer (line 73) | func NdpServer() (err error) {
FILE: cmd/imds.go
function ImdsServer (line 7) | func ImdsServer() (err error) {
FILE: cmd/instance.go
function StartInstance (line 11) | func StartInstance(name string) (err error) {
function StopInstance (line 36) | func StopInstance(name string) (err error) {
FILE: cmd/log.go
function ClearLogs (line 9) | func ClearLogs() (err error) {
FILE: cmd/mtu.go
function MtuCheck (line 7) | func MtuCheck() (err error) {
FILE: cmd/node.go
function Node (line 25) | func Node() (err error) {
FILE: cmd/optimize.go
function Optimize (line 8) | func Optimize() (err error) {
function optimizeNested (line 17) | func optimizeNested() (err error) {
FILE: cmd/settings.go
function Mongo (line 18) | func Mongo() (err error) {
function ResetNodeWeb (line 40) | func ResetNodeWeb() (err error) {
function DefaultPassword (line 83) | func DefaultPassword() (err error) {
function ResetPassword (line 107) | func ResetPassword() (err error) {
function DisablePolicies (line 153) | func DisablePolicies() (err error) {
function DisableFirewall (line 174) | func DisableFirewall() (err error) {
function SettingsSet (line 211) | func SettingsSet() (err error) {
function SettingsUnset (line 235) | func SettingsUnset() (err error) {
FILE: colorize/colorize.go
type Color (line 3) | type Color
constant None (line 6) | None = ""
constant Bold (line 7) | Bold = "\033[1m"
constant Black (line 8) | Black = "\033[0;30m"
constant BlackBold (line 9) | BlackBold = "\033[1;30m"
constant Red (line 10) | Red = "\033[0;31m"
constant RedBold (line 11) | RedBold = "\033[1;31m"
constant Green (line 12) | Green = "\033[0;32m"
constant GreenBold (line 13) | GreenBold = "\033[1;32m"
constant Yellow (line 14) | Yellow = "\033[0;33m"
constant YellowBold (line 15) | YellowBold = "\033[1;33m"
constant Blue (line 16) | Blue = "\033[0;34m"
constant BlueBold (line 17) | BlueBold = "\033[1;34m"
constant Purple (line 18) | Purple = "\033[0;35m"
constant PurpleBold (line 19) | PurpleBold = "\033[1;35m"
constant Cyan (line 20) | Cyan = "\033[0;36m"
constant CyanBold (line 21) | CyanBold = "\033[1;36m"
constant White (line 22) | White = "\033[0;37m"
constant WhiteBold (line 23) | WhiteBold = "\033[1;37m"
constant BlackBg (line 24) | BlackBg = "\033[40m"
constant RedBg (line 25) | RedBg = "\033[41m"
constant GreenBg (line 26) | GreenBg = "\033[42m"
constant YellowBg (line 27) | YellowBg = "\033[43m"
constant BlueBg (line 28) | BlueBg = "\033[44m"
constant PurpleBg (line 29) | PurpleBg = "\033[45m"
constant CyanBg (line 30) | CyanBg = "\033[46m"
constant WhiteBg (line 31) | WhiteBg = "\033[47m"
function ColorString (line 34) | func ColorString(input string, fg Color, bg Color) (str string) {
FILE: completion/completion.go
type Completion (line 30) | type Completion struct
type Build (line 53) | type Build struct
type BuildTag (line 61) | type BuildTag struct
function get (line 66) | func get(db *database.Database, coll *database.Collection,
function GetCompletion (line 97) | func GetCompletion(db *database.Database, orgId bson.ObjectID,
FILE: compositor/compositor.go
constant ProcDir (line 18) | ProcDir = "/proc"
function GetEnv (line 21) | func GetEnv(username, driPath string, driPrime bool) (
FILE: config/config.go
type ConfigData (line 26) | type ConfigData struct
method Save (line 33) | func (c *ConfigData) Save() (err error) {
function Load (line 65) | func Load() (err error) {
function Save (line 112) | func Save() (err error) {
function GetModTime (line 121) | func GetModTime() (mod time.Time, err error) {
function init (line 135) | func init() {
FILE: constants/constants.go
constant Version (line 8) | Version = "2.0.3665.99"
constant DatabaseVersion (line 9) | DatabaseVersion = 1
constant LogPath (line 10) | LogPath = "/var/log/pritunl-cloud.log"
constant LogPath2 (line 11) | LogPath2 = "/var/log/pritunl-cloud.log.1"
constant StaticCache (line 12) | StaticCache = true
constant RetryDelay (line 13) | RetryDelay = 3 * time.Second
FILE: cookie/cookie.go
type Cookie (line 23) | type Cookie struct
method Get (line 30) | func (c *Cookie) Get(key string) string {
method Set (line 38) | func (c *Cookie) Set(key string, val string) {
method GetSession (line 42) | func (c *Cookie) GetSession(db *database.Database, r *http.Request,
method NewSession (line 79) | func (c *Cookie) NewSession(db *database.Database, r *http.Request,
method Remove (line 112) | func (c *Cookie) Remove(db *database.Database) (err error) {
method Save (line 139) | func (c *Cookie) Save() (err error) {
function init (line 144) | func init() {
FILE: cookie/utils.go
function GetAdmin (line 11) | func GetAdmin(w http.ResponseWriter, r *http.Request) (
function NewAdmin (line 32) | func NewAdmin(w http.ResponseWriter, r *http.Request) (cook *Cookie) {
function CleanAdmin (line 44) | func CleanAdmin(w http.ResponseWriter, r *http.Request) {
function GetUser (line 57) | func GetUser(w http.ResponseWriter, r *http.Request) (
function NewUser (line 78) | func NewUser(w http.ResponseWriter, r *http.Request) (cook *Cookie) {
function CleanUser (line 90) | func CleanUser(w http.ResponseWriter, r *http.Request) {
FILE: crypto/crypto.go
type Message (line 18) | type Message struct
type AsymNaclHmacKey (line 24) | type AsymNaclHmacKey struct
type AsymNaclHmac (line 31) | type AsymNaclHmac struct
method RegisterNonce (line 39) | func (a *AsymNaclHmac) RegisterNonce(handler func(nonce []byte) error) {
method Seal (line 43) | func (a *AsymNaclHmac) Seal(input any) (msg *Message, err error) {
method SealJson (line 87) | func (a *AsymNaclHmac) SealJson(input any) (output string, err error) {
method Unseal (line 105) | func (a *AsymNaclHmac) Unseal(msg *Message, output any) (err error) {
method UnsealJson (line 188) | func (a *AsymNaclHmac) UnsealJson(input string, output any) (err error) {
method Export (line 207) | func (a *AsymNaclHmac) Export() AsymNaclHmacKey {
method Import (line 216) | func (a *AsymNaclHmac) Import(key AsymNaclHmacKey) (err error) {
method Generate (line 303) | func (a *AsymNaclHmac) Generate() (err error) {
FILE: csrf/csrf.go
type CsrfToken (line 10) | type CsrfToken struct
function NewToken (line 16) | func NewToken(db *database.Database, sessionId string) (
function ValidateToken (line 42) | func ValidateToken(db *database.Database, sessionId, token string) (
FILE: data/disk.go
function createDiskQcow (line 16) | func createDiskQcow(db *database.Database, dsk *disk.Disk) (
function createDiskLvm (line 47) | func createDiskLvm(db *database.Database, dsk *disk.Disk) (
function CreateDisk (line 80) | func CreateDisk(db *database.Database, dsk *disk.Disk) (
function ActivateDisk (line 106) | func ActivateDisk(db *database.Database, dsk *disk.Disk) (err error) {
function DeactivateDisk (line 127) | func DeactivateDisk(db *database.Database, dsk *disk.Disk) (err error) {
FILE: data/image.go
function getImageS3 (line 51) | func getImageS3(db *database.Database, store *storage.Storage,
type ProgressS3 (line 112) | type ProgressS3 struct
method Start (line 144) | func (p *ProgressS3) Start() {
method Stop (line 161) | func (p *ProgressS3) Stop() {
method calculateProgress (line 168) | func (p *ProgressS3) calculateProgress() {
method syncProgress (line 189) | func (p *ProgressS3) syncProgress() {
function NewProgressS3 (line 127) | func NewProgressS3(db *database.Database, dsk *disk.Disk, img *image.Image,
type Progress (line 214) | type Progress struct
method Write (line 238) | func (p *Progress) Write(data []byte) (n int, err error) {
function humanReadableSpeed (line 225) | func humanReadableSpeed(bytesPerSecond float64) string {
function getImageWeb (line 262) | func getImageWeb(db *database.Database, store *storage.Storage,
function checkImageSigS3 (line 350) | func checkImageSigS3(db *database.Database, store *storage.Storage,
function checkImageSigWeb (line 425) | func checkImageSigWeb(db *database.Database, store *storage.Storage,
function getImage (line 499) | func getImage(db *database.Database, dsk *disk.Disk, img *image.Image,
function copyBackingImage (line 596) | func copyBackingImage(imagePth, backingImagePth string) (err error) {
function writeFsQcow (line 617) | func writeFsQcow(db *database.Database, dsk *disk.Disk) (err error) {
function writeImageQcow (line 786) | func writeImageQcow(db *database.Database, dsk *disk.Disk) (
function writeFsLvm (line 1045) | func writeFsLvm(db *database.Database, dsk *disk.Disk,
function writeImageLvm (line 1205) | func writeImageLvm(db *database.Database, dsk *disk.Disk,
function DeleteImage (line 1317) | func DeleteImage(db *database.Database, imgId bson.ObjectID) (
function WriteImage (line 1359) | func WriteImage(db *database.Database, dsk *disk.Disk) (
function DeleteImages (line 1396) | func DeleteImages(db *database.Database, imgIds []bson.ObjectID) (
function DeleteImageOrg (line 1409) | func DeleteImageOrg(db *database.Database, orgId, imgId bson.ObjectID) (
function DeleteImagesOrg (line 1451) | func DeleteImagesOrg(db *database.Database, orgId bson.ObjectID,
function CreateSnapshot (line 1464) | func CreateSnapshot(db *database.Database, dsk *disk.Disk,
function CreateBackup (line 1665) | func CreateBackup(db *database.Database, dsk *disk.Disk,
function RestoreBackup (line 1845) | func RestoreBackup(db *database.Database, dsk *disk.Disk) (err error) {
function ImageAvailable (line 1950) | func ImageAvailable(store *storage.Storage, img *image.Image) (
FILE: data/resize.go
type diskInfo (line 19) | type diskInfo struct
function getQcowSize (line 26) | func getQcowSize(pth string) (size int, err error) {
function getDiskSizeQcow (line 48) | func getDiskSizeQcow(dsk *disk.Disk) (size int, err error) {
function expandDiskQcow (line 52) | func expandDiskQcow(db *database.Database, dsk *disk.Disk) (err error) {
function expandDiskLvm (line 94) | func expandDiskLvm(db *database.Database, dsk *disk.Disk) (err error) {
function ExpandDisk (line 176) | func ExpandDisk(db *database.Database, dsk *disk.Disk) (err error) {
FILE: data/sync.go
function getImagesS3 (line 43) | func getImagesS3(db *database.Database, store *storage.Storage) (
type Files (line 112) | type Files struct
type File (line 117) | type File struct
function getImagesWeb (line 124) | func getImagesWeb(db *database.Database, store *storage.Storage) (
function Sync (line 190) | func Sync(db *database.Database, store *storage.Storage) (err error) {
FILE: data/utils.go
function GetVgName (line 12) | func GetVgName(id bson.ObjectID, n int) string {
function GetLvName (line 19) | func GetLvName(id bson.ObjectID, n int) string {
FILE: database/base.go
type Named (line 7) | type Named struct
FILE: database/client.go
function getClient (line 19) | func getClient() *mongo.Client {
function setClient (line 27) | func setClient(client *mongo.Client) {
FILE: database/collection.go
type Collection (line 14) | type Collection struct
method FindOneId (line 19) | func (c *Collection) FindOneId(id interface{}, data interface{}) (err ...
method UpdateId (line 31) | func (c *Collection) UpdateId(id interface{}, data interface{}) (err e...
method Commit (line 43) | func (c *Collection) Commit(id interface{}, data interface{}) (err err...
method CommitFields (line 57) | func (c *Collection) CommitFields(id interface{}, data interface{},
method Upsert (line 71) | func (c *Collection) Upsert(query *bson.M, data interface{}) (err erro...
function SelectFields (line 83) | func SelectFields(obj interface{}, fields set.Set) (data bson.M) {
function SelectFieldsAll (line 167) | func SelectFieldsAll(obj interface{}, fields set.Set) (data bson.M) {
type ArraySelectFields (line 273) | type ArraySelectFields struct
method Modified (line 285) | func (a *ArraySelectFields) Modified() bool {
method Update (line 289) | func (a *ArraySelectFields) Update(docId bson.ObjectID,
method Push (line 308) | func (a *ArraySelectFields) Push(doc interface{}) {
method Delete (line 313) | func (a *ArraySelectFields) Delete(docId bson.ObjectID) {
method GetQuery (line 318) | func (a *ArraySelectFields) GetQuery() (query bson.M, filters []interf...
function NewArraySelectFields (line 350) | func NewArraySelectFields(obj interface{}, rootKey string, fields set.Se...
FILE: database/database.go
type Database (line 21) | type Database struct
method Deadline (line 27) | func (d *Database) Deadline() (time.Time, bool) {
method Done (line 34) | func (d *Database) Done() <-chan struct{} {
method Err (line 41) | func (d *Database) Err() error {
method Value (line 48) | func (d *Database) Value(key interface{}) interface{} {
method String (line 55) | func (d *Database) String() string {
method Close (line 59) | func (d *Database) Close() {
method GetCollection (line 62) | func (d *Database) GetCollection(name string) (coll *Collection) {
method getCollectionWeak (line 70) | func (d *Database) getCollectionWeak(name string) (coll *Collection) {
method getCollectionStrong (line 82) | func (d *Database) getCollectionStrong(name string) (coll *Collection) {
method Users (line 94) | func (d *Database) Users() (coll *Collection) {
method Policies (line 99) | func (d *Database) Policies() (coll *Collection) {
method Devices (line 104) | func (d *Database) Devices() (coll *Collection) {
method Alerts (line 109) | func (d *Database) Alerts() (coll *Collection) {
method AlertsEvent (line 114) | func (d *Database) AlertsEvent() (coll *Collection) {
method AlertsEventLock (line 119) | func (d *Database) AlertsEventLock() (coll *Collection) {
method Pods (line 124) | func (d *Database) Pods() (coll *Collection) {
method Units (line 129) | func (d *Database) Units() (coll *Collection) {
method Specs (line 134) | func (d *Database) Specs() (coll *Collection) {
method Deployments (line 139) | func (d *Database) Deployments() (coll *Collection) {
method Sessions (line 144) | func (d *Database) Sessions() (coll *Collection) {
method Tasks (line 149) | func (d *Database) Tasks() (coll *Collection) {
method Tokens (line 154) | func (d *Database) Tokens() (coll *Collection) {
method CsrfTokens (line 159) | func (d *Database) CsrfTokens() (coll *Collection) {
method SecondaryTokens (line 164) | func (d *Database) SecondaryTokens() (coll *Collection) {
method Nonces (line 169) | func (d *Database) Nonces() (coll *Collection) {
method Rokeys (line 174) | func (d *Database) Rokeys() (coll *Collection) {
method Schedulers (line 179) | func (d *Database) Schedulers() (coll *Collection) {
method Settings (line 184) | func (d *Database) Settings() (coll *Collection) {
method Events (line 189) | func (d *Database) Events() (coll *Collection) {
method Nodes (line 194) | func (d *Database) Nodes() (coll *Collection) {
method NodePorts (line 199) | func (d *Database) NodePorts() (coll *Collection) {
method Organizations (line 204) | func (d *Database) Organizations() (coll *Collection) {
method Storages (line 209) | func (d *Database) Storages() (coll *Collection) {
method Images (line 214) | func (d *Database) Images() (coll *Collection) {
method Datacenters (line 219) | func (d *Database) Datacenters() (coll *Collection) {
method Zones (line 224) | func (d *Database) Zones() (coll *Collection) {
method Shapes (line 229) | func (d *Database) Shapes() (coll *Collection) {
method Balancers (line 234) | func (d *Database) Balancers() (coll *Collection) {
method Advisories (line 239) | func (d *Database) Advisories() (coll *Collection) {
method Instances (line 244) | func (d *Database) Instances() (coll *Collection) {
method Pools (line 249) | func (d *Database) Pools() (coll *Collection) {
method Disks (line 254) | func (d *Database) Disks() (coll *Collection) {
method Blocks (line 259) | func (d *Database) Blocks() (coll *Collection) {
method BlocksIp (line 264) | func (d *Database) BlocksIp() (coll *Collection) {
method LvmLock (line 269) | func (d *Database) LvmLock() (coll *Collection) {
method Journal (line 274) | func (d *Database) Journal() (coll *Collection) {
method Firewalls (line 279) | func (d *Database) Firewalls() (coll *Collection) {
method Versions (line 284) | func (d *Database) Versions() (coll *Collection) {
method Plans (line 289) | func (d *Database) Plans() (coll *Collection) {
method Vpcs (line 294) | func (d *Database) Vpcs() (coll *Collection) {
method VpcsIp (line 299) | func (d *Database) VpcsIp() (coll *Collection) {
method Authorities (line 304) | func (d *Database) Authorities() (coll *Collection) {
method Certificates (line 309) | func (d *Database) Certificates() (coll *Collection) {
method Secrets (line 314) | func (d *Database) Secrets() (coll *Collection) {
method Domains (line 319) | func (d *Database) Domains() (coll *Collection) {
method DomainsRecords (line 324) | func (d *Database) DomainsRecords() (coll *Collection) {
method AcmeChallenges (line 329) | func (d *Database) AcmeChallenges() (coll *Collection) {
method Logs (line 334) | func (d *Database) Logs() (coll *Collection) {
method Audits (line 339) | func (d *Database) Audits() (coll *Collection) {
method Geo (line 344) | func (d *Database) Geo() (coll *Collection) {
function Connect (line 349) | func Connect() (err error) {
function ValidateDatabase (line 413) | func ValidateDatabase() (version string, err error) {
function getDatabase (line 469) | func getDatabase(ctx context.Context, client *mongo.Client) *Database {
function GetDatabase (line 483) | func GetDatabase() *Database {
function GetDatabaseCtx (line 487) | func GetDatabaseCtx(ctx context.Context) *Database {
function addIndexes (line 491) | func addIndexes() (err error) {
function addCollections (line 1347) | func addCollections() (err error) {
function init (line 1422) | func init() {
FILE: database/errors.go
type ConnectionError (line 7) | type ConnectionError struct
type IndexError (line 11) | type IndexError struct
type NotFoundError (line 15) | type NotFoundError struct
type ImmutableKeyError (line 19) | type ImmutableKeyError struct
type DuplicateKeyError (line 23) | type DuplicateKeyError struct
type UnknownError (line 27) | type UnknownError struct
type CertificateError (line 31) | type CertificateError struct
type IndexConflict (line 35) | type IndexConflict struct
FILE: database/index.go
type bsonIndex (line 23) | type bsonIndex struct
type Index (line 27) | type Index struct
method Create (line 94) | func (i *Index) Create() (err error) {
function GenerateIndexName (line 35) | func GenerateIndexName(doc bson.D) (indexName string, err error) {
function CleanIndexes (line 164) | func CleanIndexes(db *Database) (err error) {
FILE: database/utils.go
function FindProject (line 13) | func FindProject(fields ...string) *options.FindOptionsBuilder {
function FindOneProject (line 26) | func FindOneProject(fields ...string) *options.FindOneOptionsBuilder {
function GetErrorCodes (line 39) | func GetErrorCodes(err error) (errCodes []int) {
function ParseError (line 99) | func ParseError(err error) (newErr error) {
function IgnoreNotFoundError (line 135) | func IgnoreNotFoundError(err error) (newErr error) {
FILE: datacenter/constants.go
constant Default (line 4) | Default = "default"
constant VxlanVlan (line 5) | VxlanVlan = "vxlan_vlan"
constant WgVxlanVlan (line 6) | WgVxlanVlan = "wg_vxlan_vlan"
constant Wg4 (line 8) | Wg4 = "wg4"
constant Wg6 (line 9) | Wg6 = "wg6"
FILE: datacenter/datacenter.go
type Datacenter (line 14) | type Datacenter struct
method Validate (line 36) | func (d *Datacenter) Validate(db *database.Database) (
method Vxlan (line 98) | func (d *Datacenter) Vxlan() bool {
method GetBaseInternalMtu (line 102) | func (d *Datacenter) GetBaseInternalMtu() (mtuSize int) {
method GetBaseExternalMtu (line 115) | func (d *Datacenter) GetBaseExternalMtu() (mtuSize int) {
method GetOverlayMtu (line 128) | func (d *Datacenter) GetOverlayMtu() (mtuSize int) {
method GetInstanceMtu (line 164) | func (d *Datacenter) GetInstanceMtu() (mtuSize int) {
method Commit (line 200) | func (d *Datacenter) Commit(db *database.Database) (err error) {
method CommitFields (line 211) | func (d *Datacenter) CommitFields(db *database.Database, fields set.Se...
method Insert (line 224) | func (d *Datacenter) Insert(db *database.Database) (err error) {
type Completion (line 30) | type Completion struct
FILE: datacenter/utils.go
function Get (line 10) | func Get(db *database.Database, dcId bson.ObjectID) (
function ExistsOrg (line 24) | func ExistsOrg(db *database.Database, orgId, dcId bson.ObjectID) (
function GetAll (line 52) | func GetAll(db *database.Database) (dcs []*Datacenter, err error) {
function GetOne (line 83) | func GetOne(db *database.Database, query *bson.M) (dc *Datacenter, err e...
function GetAllNamesOrg (line 96) | func GetAllNamesOrg(db *database.Database, orgId bson.ObjectID) (
function GetAllNames (line 144) | func GetAllNames(db *database.Database, query *bson.M) (
function GetAllPaged (line 186) | func GetAllPaged(db *database.Database, query *bson.M,
function DistinctOrg (line 250) | func DistinctOrg(db *database.Database, orgId bson.ObjectID) (
function Remove (line 274) | func Remove(db *database.Database, dcId bson.ObjectID) (err error) {
function RemoveMulti (line 293) | func RemoveMulti(db *database.Database, dcIds []bson.ObjectID) (
function RemoveMultiOrg (line 310) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: defaults/defaults.go
function initStorage (line 31) | func initStorage(db *database.Database) (err error) {
function initOrganization (line 77) | func initOrganization(db *database.Database) (
function initDatacenter (line 130) | func initDatacenter(db *database.Database) (
function initZone (line 200) | func initZone(db *database.Database, defaultDc bson.ObjectID) (
function initVpc (line 245) | func initVpc(db *database.Database, defaultOrg,
function initFirewall (line 313) | func initFirewall(db *database.Database, defaultOrg bson.ObjectID) (
function initAuthority (line 505) | func initAuthority(db *database.Database, defaultOrg bson.ObjectID) (
function initNode (line 558) | func initNode(db *database.Database, defaultOrg bson.ObjectID) (
function Defaults (line 835) | func Defaults() (err error) {
FILE: demo/demo.go
function IsDemo (line 9) | func IsDemo() bool {
function Blocked (line 13) | func Blocked(c *gin.Context) bool {
function BlockedSilent (line 27) | func BlockedSilent(c *gin.Context) bool {
FILE: demo/rand.go
function RandIp (line 18) | func RandIp(instId bson.ObjectID) (addr string) {
function RandIp6 (line 31) | func RandIp6(instId bson.ObjectID) (addr string) {
function RandPrivateIp (line 44) | func RandPrivateIp(instId bson.ObjectID) (addr string) {
function RandPrivateIp6 (line 57) | func RandPrivateIp6(instId bson.ObjectID) (addr string) {
FILE: deploy/deploy.go
function Deploy (line 10) | func Deploy(stat *state.State, runtimes *state.Runtimes) (err error) {
FILE: deploy/deployments.go
type Deployments (line 33) | type Deployments struct
method migrate (line 37) | func (d *Deployments) migrate(deply *deployment.Deployment) {
method destroy (line 362) | func (d *Deployments) destroy(deply *deployment.Deployment) {
method archive (line 467) | func (d *Deployments) archive(deply *deployment.Deployment) (err error) {
method restore (line 552) | func (d *Deployments) restore(deply *deployment.Deployment) (err error) {
method imageShutdown (line 715) | func (d *Deployments) imageShutdown(db *database.Database,
method image (line 760) | func (d *Deployments) image(deply *deployment.Deployment) (err error) {
method domainCommit (line 845) | func (d *Deployments) domainCommit(deply *deployment.Deployment,
method domain (line 934) | func (d *Deployments) domain(db *database.Database,
method Deploy (line 1150) | func (d *Deployments) Deploy(db *database.Database) (err error) {
function NewDeployments (line 1206) | func NewDeployments(stat *state.State) *Deployments {
FILE: deploy/disks.go
type Disks (line 27) | type Disks struct
method provision (line 31) | func (d *Disks) provision(dsk *disk.Disk) {
method snapshot (line 83) | func (d *Disks) snapshot(dsk *disk.Disk) {
method expand (line 150) | func (d *Disks) expand(dsk *disk.Disk) {
method backup (line 226) | func (d *Disks) backup(dsk *disk.Disk) {
method restore (line 301) | func (d *Disks) restore(dsk *disk.Disk) {
method destroy (line 394) | func (d *Disks) destroy(db *database.Database, dsk *disk.Disk) {
method scheduleBackup (line 467) | func (d *Disks) scheduleBackup(dsk *disk.Disk) {
method Deploy (line 551) | func (d *Disks) Deploy(db *database.Database) (err error) {
function NewDisks (line 594) | func NewDisks(stat *state.State) *Disks {
FILE: deploy/imds.go
type Imds (line 23) | type Imds struct
method buildInstance (line 27) | func (s *Imds) buildInstance(db *database.Database,
method buildDeployInstance (line 60) | func (s *Imds) buildDeployInstance(db *database.Database,
method Deploy (line 156) | func (s *Imds) Deploy(db *database.Database) (err error) {
function NewImds (line 197) | func NewImds(stat *state.State) *Imds {
FILE: deploy/instances.go
type Instances (line 41) | type Instances struct
method create (line 45) | func (s *Instances) create(inst *instance.Instance) {
method start (line 94) | func (s *Instances) start(inst *instance.Instance) {
method cleanup (line 156) | func (s *Instances) cleanup(inst *instance.Instance) {
method stop (line 193) | func (s *Instances) stop(inst *instance.Instance) {
method restart (line 228) | func (s *Instances) restart(inst *instance.Instance) {
method destroy (line 311) | func (s *Instances) destroy(inst *instance.Instance) {
method diskAdd (line 377) | func (s *Instances) diskAdd(inst *instance.Instance,
method diskRemove (line 435) | func (s *Instances) diskRemove(inst *instance.Instance,
method usbAdd (line 488) | func (s *Instances) usbAdd(inst *instance.Instance, virt *vm.VirtualMa...
method usbRemove (line 541) | func (s *Instances) usbRemove(inst *instance.Instance,
method diff (line 594) | func (s *Instances) diff(db *database.Database,
method check (line 653) | func (s *Instances) check(inst *instance.Instance, namespaces set.Set) (
method routes (line 670) | func (s *Instances) routes(inst *instance.Instance) (err error) {
method Deploy (line 886) | func (s *Instances) Deploy(db *database.Database) (err error) {
function NewInstances (line 1076) | func NewInstances(stat *state.State) *Instances {
FILE: deploy/ipset.go
type Ipset (line 8) | type Ipset struct
method Deploy (line 12) | func (t *Ipset) Deploy() (err error) {
method Clean (line 26) | func (t *Ipset) Clean() (err error) {
function NewIpset (line 39) | func NewIpset(stat *state.State) *Ipset {
FILE: deploy/iptables.go
type Iptables (line 8) | type Iptables struct
method Deploy (line 12) | func (t *Iptables) Deploy() (err error) {
function NewIptables (line 27) | func NewIptables(stat *state.State) *Iptables {
FILE: deploy/namespace.go
type Namespace (line 22) | type Namespace struct
method Deploy (line 26) | func (n *Namespace) Deploy(db *database.Database) (err error) {
function NewNamespace (line 114) | func NewNamespace(stat *state.State) *Namespace {
FILE: deploy/network.go
type Network (line 24) | type Network struct
method Deploy (line 28) | func (d *Network) Deploy() (err error) {
function NewNetwork (line 49) | func NewNetwork(stat *state.State) *Network {
function nodePortCreate (line 55) | func nodePortCreate() (err error) {
function nodePortGetAddr (line 75) | func nodePortGetAddr() (addr string, err error) {
function nodePortSetAddr (line 89) | func nodePortSetAddr(addr string) (err error) {
function nodePortClearAddr (line 120) | func nodePortClearAddr() (err error) {
function nodePortRemoveNetwork (line 142) | func nodePortRemoveNetwork(stat *state.State) (err error) {
function NodePortApplyState (line 157) | func NodePortApplyState(stat *state.State) (err error) {
FILE: deploy/services.go
type Pods (line 28) | type Pods struct
method processSchedule (line 32) | func (s *Pods) processSchedule(schd *scheduler.Scheduler) {
method deploySchedule (line 60) | func (s *Pods) deploySchedule(schd *scheduler.Scheduler) (err error) {
method DeploySpec (line 174) | func (s *Pods) DeploySpec(db *database.Database,
method Deploy (line 491) | func (s *Pods) Deploy(db *database.Database) (err error) {
function NewPods (line 530) | func NewPods(stat *state.State) *Pods {
FILE: deployment/constants.go
constant Provision (line 10) | Provision = "provision"
constant Reserved (line 11) | Reserved = "reserved"
constant Deployed (line 12) | Deployed = "deployed"
constant Archived (line 13) | Archived = "archived"
constant Destroy (line 15) | Destroy = "destroy"
constant Archive (line 16) | Archive = "archive"
constant Migrate (line 17) | Migrate = "migrate"
constant Restore (line 18) | Restore = "restore"
constant Ready (line 20) | Ready = "ready"
constant Snapshot (line 21) | Snapshot = "snapshot"
constant Complete (line 22) | Complete = "complete"
constant Failed (line 23) | Failed = "failed"
constant Instance (line 25) | Instance = "instance"
constant Image (line 26) | Image = "image"
constant Firewall (line 27) | Firewall = "firewall"
constant Domain (line 28) | Domain = "domain"
constant Healthy (line 30) | Healthy = "healthy"
constant Unknown (line 31) | Unknown = "unknown"
constant Unhealthy (line 32) | Unhealthy = "unhealthy"
constant ThresholdMin (line 34) | ThresholdMin = 10
constant ActionLimit (line 35) | ActionLimit = 1 * time.Minute
FILE: deployment/deployment.go
type Deployment (line 14) | type Deployment struct
method IsHealthy (line 83) | func (d *Deployment) IsHealthy() bool {
method Validate (line 87) | func (d *Deployment) Validate(db *database.Database) (
method HandleStatement (line 163) | func (d *Deployment) HandleStatement(db *database.Database,
method SetImageState (line 244) | func (d *Deployment) SetImageState(state string) {
method GetImageState (line 251) | func (d *Deployment) GetImageState() string {
method ImageReady (line 258) | func (d *Deployment) ImageReady() bool {
method CommitAction (line 263) | func (d *Deployment) CommitAction(db *database.Database,
method RemoveAction (line 283) | func (d *Deployment) RemoveAction(db *database.Database,
method Commit (line 303) | func (d *Deployment) Commit(db *database.Database) (err error) {
method CommitFields (line 314) | func (d *Deployment) CommitFields(db *database.Database, fields set.Se...
method Insert (line 327) | func (d *Deployment) Insert(db *database.Database) (err error) {
type InstanceData (line 40) | type InstanceData struct
type DomainData (line 51) | type DomainData struct
type RecordData (line 55) | type RecordData struct
type ImageData (line 60) | type ImageData struct
type Mount (line 64) | type Mount struct
type Journal (line 70) | type Journal struct
type Action (line 76) | type Action struct
FILE: deployment/utils.go
function Get (line 13) | func Get(db *database.Database, deplyId bson.ObjectID) (
function GetUnit (line 27) | func GetUnit(db *database.Database, unitId, deplyId bson.ObjectID) (
function GetOrg (line 45) | func GetOrg(db *database.Database, orgId, unitId bson.ObjectID) (
function GetUnitOrg (line 63) | func GetUnitOrg(db *database.Database,
function GetAll (line 83) | func GetAll(db *database.Database, query *bson.M) (
function GetAllSorted (line 116) | func GetAllSorted(db *database.Database, query *bson.M) (
function GetAllActiveIds (line 156) | func GetAllActiveIds(db *database.Database) (deplyIds set.Set, err error) {
function GetAllStates (line 201) | func GetAllStates(db *database.Database) (
function RemoveDomains (line 243) | func RemoveDomains(db *database.Database, deplyId bson.ObjectID) (
function Remove (line 304) | func Remove(db *database.Database, deplyId bson.ObjectID) (err error) {
function RemoveMulti (line 335) | func RemoveMulti(db *database.Database, unitId bson.ObjectID,
function ArchiveMulti (line 358) | func ArchiveMulti(db *database.Database, unitId bson.ObjectID,
function RestoreMulti (line 382) | func RestoreMulti(db *database.Database, unitId bson.ObjectID,
FILE: device/constants.go
constant U2f (line 4) | U2f = "u2f"
constant WebAuthn (line 5) | WebAuthn = "webauthn"
constant Secondary (line 6) | Secondary = "secondary"
constant Phone (line 7) | Phone = "phone"
constant Call (line 8) | Call = "call"
constant Message (line 9) | Message = "message"
constant Low (line 10) | Low = 1
constant Medium (line 11) | Medium = 5
constant High (line 12) | High = 10
FILE: device/device.go
type Device (line 18) | type Device struct
method Validate (line 41) | func (d *Device) Validate(db *database.Database) (
method SetActive (line 121) | func (d *Device) SetActive(db *database.Database) (err error) {
method MarshalWebauthn (line 131) | func (d *Device) MarshalWebauthn(cred *webauthn.Credential) {
method UnmarshalWebauthn (line 144) | func (d *Device) UnmarshalWebauthn() (cred webauthn.Credential, err er...
method CheckLevel (line 185) | func (d *Device) CheckLevel(level int) bool {
method Commit (line 199) | func (d *Device) Commit(db *database.Database) (err error) {
method CommitFields (line 210) | func (d *Device) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 223) | func (d *Device) Insert(db *database.Database) (err error) {
FILE: device/facet.go
type FacetVersion (line 7) | type FacetVersion struct
type TrustedFacet (line 12) | type TrustedFacet struct
type Facets (line 17) | type Facets struct
function GetFacets (line 21) | func GetFacets() (facets *Facets) {
FILE: device/utils.go
function Get (line 11) | func Get(db *database.Database, devcId bson.ObjectID) (
function GetUser (line 25) | func GetUser(db *database.Database, devcId bson.ObjectID,
function GetAll (line 43) | func GetAll(db *database.Database, userId bson.ObjectID) (
function GetAllSorted (line 78) | func GetAllSorted(db *database.Database, userId bson.ObjectID) (
function GetAllMode (line 118) | func GetAllMode(db *database.Database, userId bson.ObjectID,
function CountSecondary (line 154) | func CountSecondary(db *database.Database, userId bson.ObjectID) (
function New (line 171) | func New(userId bson.ObjectID, typ, mode string) (devc *Device) {
function Remove (line 184) | func Remove(db *database.Database, id bson.ObjectID) (err error) {
function RemoveUser (line 204) | func RemoveUser(db *database.Database, id bson.ObjectID,
function RemoveAll (line 227) | func RemoveAll(db *database.Database, userId bson.ObjectID) (err error) {
FILE: dhcpc/constants.go
constant MaxMessageSize (line 8) | MaxMessageSize = 1500
constant DefaultInterval (line 9) | DefaultInterval = 60 * time.Second
constant DhcpTimeout (line 10) | DhcpTimeout = 10 * time.Second
constant DhcpRetries (line 11) | DhcpRetries = 3
FILE: dhcpc/dhcpc.go
type Dhcpc (line 16) | type Dhcpc struct
method startSync (line 29) | func (d *Dhcpc) startSync() {
method sync (line 64) | func (d *Dhcpc) sync() {
method run4 (line 71) | func (d *Dhcpc) run4() (err error) {
method run6 (line 171) | func (d *Dhcpc) run6() (err error) {
method Run (line 270) | func (d *Dhcpc) Run(ip4, ip6 bool) {
function Main (line 324) | func Main() (err error) {
FILE: dhcpc/imds.go
type SyncData (line 23) | type SyncData struct
type Imds (line 30) | type Imds struct
method NewRequest (line 36) | func (m *Imds) NewRequest(method, pth string, data interface{}) (
method Sync (line 75) | func (m *Imds) Sync(lease *Lease) (err error) {
FILE: dhcpc/lease.go
type Lease (line 10) | type Lease struct
method IfaceReady (line 28) | func (l *Lease) IfaceReady() (ready4, ready6 bool) {
FILE: dhcpc/lease4.go
method Renew4 (line 13) | func (l *Lease) Renew4() (ok bool, err error) {
method Exchange4 (line 82) | func (l *Lease) Exchange4() (ok bool, err error) {
FILE: dhcpc/lease6.go
method Renew6 (line 14) | func (l *Lease) Renew6() (ok bool, err error) {
method Exchange6 (line 121) | func (l *Lease) Exchange6() (ok bool, err error) {
function extractDhcpv6Lease (line 200) | func extractDhcpv6Lease(reply *dhcpv6.Message, ifaceName string) *Lease {
FILE: dhcpc/systemd.go
constant systemdNamespaceTemplate (line 21) | systemdNamespaceTemplate = `[Unit]
constant systemdTemplate (line 49) | systemdTemplate = `[Unit]
function WriteService (line 76) | func WriteService(vmId bson.ObjectID,
function Start (line 144) | func Start(db *database.Database, virt *vm.VirtualMachine,
function Stop (line 178) | func Stop(virt *vm.VirtualMachine) (err error) {
FILE: dhcpc/utils.go
function buildDhLease (line 13) | func buildDhLease(lease *Lease, addr net.HardwareAddr) (
function extractDhLease (line 66) | func extractDhLease(dhLease *nclient4.Lease) (lease *Lease) {
function TransactionIdUnmarshal (line 106) | func TransactionIdUnmarshal(str string) dhcpv4.TransactionID {
FILE: dhcps/dhcp4.go
type Server4 (line 15) | type Server4 struct
method handler (line 29) | func (s *Server4) handler(conn net.PacketConn, peer net.Addr,
method handleMsg (line 43) | func (s *Server4) handleMsg(conn net.PacketConn, peer net.Addr,
method Start (line 109) | func (s *Server4) Start() (err error) {
FILE: dhcps/dhcp6.go
type Server6 (line 16) | type Server6 struct
method handler (line 33) | func (s *Server6) handler(conn net.PacketConn, peer net.Addr,
method handleMsg (line 47) | func (s *Server6) handleMsg(conn net.PacketConn, peer net.Addr,
method process (line 168) | func (s *Server6) process(msg *dhcpv6.Message,
method Start (line 252) | func (s *Server6) Start() (err error) {
FILE: dhcps/ndp.go
type ServerNdp (line 15) | type ServerNdp struct
method Start (line 32) | func (s *ServerNdp) Start() (err error) {
method run (line 95) | func (s *ServerNdp) run() (err error) {
method sendAdvertise (line 121) | func (s *ServerNdp) sendAdvertise(conn *ndp.Conn, dst netip.Addr) (err...
method readSolicitations (line 188) | func (s *ServerNdp) readSolicitations(conn *ndp.Conn) (err error) {
FILE: dhcps/systemd.go
constant dhcpCaps (line 27) | dhcpCaps = "CAP_NET_BIND_SERVICE CAP_NET_BROADCAST"
constant ndpCaps (line 28) | ndpCaps = "CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW"
constant systemdTemplate (line 31) | systemdTemplate = `[Unit]
constant systemdNamespaceTemplate (line 49) | systemdNamespaceTemplate = `[Unit]
function UpdateEbtables (line 68) | func UpdateEbtables(vmId bson.ObjectID, namespace string) (err error) {
function ClearEbtables (line 191) | func ClearEbtables(vmId bson.ObjectID, namespace string) (err error) {
function WriteService (line 290) | func WriteService(vmId bson.ObjectID, namespace string,
function Start (line 368) | func Start(db *database.Database, virt *vm.VirtualMachine,
function Stop (line 483) | func Stop(virt *vm.VirtualMachine) (err error) {
FILE: disk/constants.go
constant Provision (line 9) | Provision = "provision"
constant Available (line 10) | Available = "available"
constant Attached (line 11) | Attached = "attached"
constant Snapshot (line 13) | Snapshot = "snapshot"
constant Backup (line 14) | Backup = "backup"
constant Expand (line 15) | Expand = "expand"
constant Restore (line 16) | Restore = "restore"
constant Destroy (line 17) | Destroy = "destroy"
constant Qcow2 (line 19) | Qcow2 = "qcow2"
constant Lvm (line 20) | Lvm = "lvm"
constant Xfs (line 22) | Xfs = "xfs"
constant Ext4 (line 23) | Ext4 = "ext4"
constant LvmXfs (line 24) | LvmXfs = "lvm_xfs"
constant LvmExt4 (line 25) | LvmExt4 = "lvm_ext4"
constant Linux (line 27) | Linux = "linux"
constant LinuxLegacy (line 28) | LinuxLegacy = "linux_legacy"
constant LinuxUnsigned (line 29) | LinuxUnsigned = "linux_unsigned"
constant Bsd (line 30) | Bsd = "bsd"
constant AlpineLinux (line 32) | AlpineLinux = "alpinelinux"
constant ArchLinux (line 33) | ArchLinux = "archlinux"
constant RedHat (line 34) | RedHat = "redhat"
constant Fedora (line 35) | Fedora = "fedora"
constant Ubuntu (line 36) | Ubuntu = "ubuntu"
constant FreeBSD (line 37) | FreeBSD = "freebsd"
FILE: disk/disk.go
type Disk (line 23) | type Disk struct
method IsActive (line 58) | func (d *Disk) IsActive() bool {
method IsAvailable (line 62) | func (d *Disk) IsAvailable() bool {
method Validate (line 69) | func (d *Disk) Validate(db *database.Database) (
method PreCommit (line 293) | func (d *Disk) PreCommit() {
method Reserve (line 298) | func (d *Disk) Reserve(db *database.Database,
method Unreserve (line 326) | func (d *Disk) Unreserve(db *database.Database,
method Commit (line 350) | func (d *Disk) Commit(db *database.Database) (err error) {
method CommitFields (line 361) | func (d *Disk) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 374) | func (d *Disk) Insert(db *database.Database) (err error) {
method Destroy (line 388) | func (d *Disk) Destroy(db *database.Database) (err error) {
FILE: disk/sort.go
type Disks (line 3) | type Disks
method Len (line 5) | func (d Disks) Len() int {
method Swap (line 9) | func (d Disks) Swap(i, j int) {
method Less (line 13) | func (d Disks) Less(i, j int) bool {
FILE: disk/utils.go
function Get (line 13) | func Get(db *database.Database, diskId bson.ObjectID) (
function GetOne (line 27) | func GetOne(db *database.Database, query *bson.M) (dsk *Disk, err error) {
function GetOrg (line 40) | func GetOrg(db *database.Database, orgId, diskId bson.ObjectID) (
function GetAll (line 58) | func GetAll(db *database.Database, query *bson.M) (
function GetAllMap (line 91) | func GetAllMap(db *database.Database, query *bson.M) (
function GetAllPaged (line 124) | func GetAllPaged(db *database.Database, query *bson.M,
function GetInstance (line 188) | func GetInstance(db *database.Database, instId bson.ObjectID) (
function GetInstanceIndex (line 228) | func GetInstanceIndex(db *database.Database, instId bson.ObjectID,
function GetNode (line 246) | func GetNode(db *database.Database, nodeId bson.ObjectID,
function Remove (line 286) | func Remove(db *database.Database, diskId bson.ObjectID) (err error) {
function Detach (line 305) | func Detach(db *database.Database, dskIds bson.ObjectID) (err error) {
function Delete (line 323) | func Delete(db *database.Database, dskId bson.ObjectID) (err error) {
function DeleteOrg (line 339) | func DeleteOrg(db *database.Database, orgId, dskId bson.ObjectID) (
function DeleteMulti (line 360) | func DeleteMulti(db *database.Database, dskIds []bson.ObjectID) (
function DeleteMultiOrg (line 385) | func DeleteMultiOrg(db *database.Database, orgId bson.ObjectID,
function UpdateMulti (line 411) | func UpdateMulti(db *database.Database, dskIds []bson.ObjectID,
function UpdateMultiOrg (line 439) | func UpdateMultiOrg(db *database.Database, orgId bson.ObjectID,
function GetAllKeys (line 473) | func GetAllKeys(db *database.Database, ndeId bson.ObjectID) (
function SetDeleteProtection (line 515) | func SetDeleteProtection(db *database.Database, instId bson.ObjectID,
FILE: dns/aws.go
type Aws (line 18) | type Aws struct
method Connect (line 24) | func (a *Aws) Connect(db *database.Database,
method DnsZoneFind (line 53) | func (a *Aws) DnsZoneFind(domain string) (zoneId string, err error) {
method DnsCommit (line 90) | func (a *Aws) DnsCommit(db *database.Database,
method DnsFind (line 223) | func (a *Aws) DnsFind(db *database.Database, domain, recordType string) (
method DnsTxtGet (line 273) | func (a *Aws) DnsTxtGet(db *database.Database, domain string) (
method DnsTxtUpsert (line 312) | func (a *Aws) DnsTxtUpsert(db *database.Database,
method DnsTxtDelete (line 353) | func (a *Aws) DnsTxtDelete(db *database.Database,
FILE: dns/cloudflare.go
type Cloudflare (line 14) | type Cloudflare struct
method Connect (line 20) | func (c *Cloudflare) Connect(db *database.Database,
method DnsZoneFind (line 43) | func (c *Cloudflare) DnsZoneFind(db *database.Database, domain string) (
method DnsCommit (line 80) | func (c *Cloudflare) DnsCommit(db *database.Database,
method DnsFind (line 276) | func (c *Cloudflare) DnsFind(db *database.Database,
method DnsTxtGet (line 323) | func (c *Cloudflare) DnsTxtGet(db *database.Database,
method DnsTxtUpsert (line 362) | func (c *Cloudflare) DnsTxtUpsert(db *database.Database,
method DnsTxtDelete (line 440) | func (c *Cloudflare) DnsTxtDelete(db *database.Database,
FILE: dns/constants.go
constant UPSERT (line 4) | UPSERT = "upsert"
constant DELETE (line 5) | DELETE = "delete"
constant RETAIN (line 6) | RETAIN = "retain"
FILE: dns/dns.go
type Operation (line 8) | type Operation struct
type Service (line 13) | type Service interface
FILE: dns/errors.go
type NotFoundError (line 7) | type NotFoundError struct
type ServiceError (line 11) | type ServiceError struct
type UnknownError (line 15) | type UnknownError struct
FILE: dns/google.go
type Google (line 20) | type Google struct
method Connect (line 45) | func (g *Google) Connect(db *database.Database,
method DnsZoneFind (line 96) | func (g *Google) DnsZoneFind(db *database.Database, domain string) (
method DnsCommit (line 158) | func (g *Google) DnsCommit(db *database.Database,
method DnsFind (line 283) | func (g *Google) DnsFind(db *database.Database, domain, recordType str...
type googleKey (line 26) | type googleKey struct
type googleZoneInfo (line 39) | type googleZoneInfo struct
FILE: dns/oracle.go
type Oracle (line 15) | type Oracle struct
method OracleUser (line 21) | func (o *Oracle) OracleUser() string {
method OraclePrivateKey (line 25) | func (o *Oracle) OraclePrivateKey() string {
method Connect (line 29) | func (o *Oracle) Connect(db *database.Database,
method DnsZoneFind (line 49) | func (o *Oracle) DnsZoneFind(db *database.Database, domain string) (
method DnsCommit (line 100) | func (o *Oracle) DnsCommit(db *database.Database,
method DnsFind (line 227) | func (o *Oracle) DnsFind(db *database.Database,
method DnsTxtGet (line 271) | func (o *Oracle) DnsTxtGet(db *database.Database,
method DnsTxtUpsert (line 306) | func (o *Oracle) DnsTxtUpsert(db *database.Database,
method DnsTxtDelete (line 344) | func (o *Oracle) DnsTxtDelete(db *database.Database,
FILE: dns/utils.go
function matchDomains (line 10) | func matchDomains(x, y string) bool {
function matchTxt (line 17) | func matchTxt(x, y string) bool {
function normalizeIp (line 24) | func normalizeIp(addr string) string {
function extractDomain (line 33) | func extractDomain(domain string) string {
function cleanDomain (line 42) | func cleanDomain(domain string) string {
FILE: dnss/constants.go
constant Ttl (line 4) | Ttl = 10
FILE: dnss/database.go
type Database (line 15) | type Database struct
function init (line 21) | func init() {
function UpdateDatabase (line 29) | func UpdateDatabase(db *Database) {
function LoadConfig (line 33) | func LoadConfig(domains []*types.Domain) {
FILE: dnss/dnss.go
type Server (line 15) | type Server struct
method ListenUdp (line 21) | func (s *Server) ListenUdp() (err error) {
method ListenTcp (line 33) | func (s *Server) ListenTcp() (err error) {
method Shutdown (line 45) | func (s *Server) Shutdown() (err error) {
function NewServer (line 59) | func NewServer(host string) (server *Server) {
FILE: dnss/plugin.go
type Plugin (line 10) | type Plugin struct
method ServeDNS (line 14) | func (p *Plugin) ServeDNS(ctx context.Context,
method Name (line 183) | func (p *Plugin) Name() string {
FILE: dnss/response.go
type Response (line 7) | type Response struct
method WriteMsg (line 12) | func (r *Response) WriteMsg(m *dns.Msg) error {
FILE: domain/constants.go
constant Local (line 6) | Local = "local"
constant AWS (line 7) | AWS = "aws"
constant Cloudflare (line 8) | Cloudflare = "cloudflare"
constant OracleCloud (line 9) | OracleCloud = "oracle_cloud"
constant A (line 11) | A = "A"
constant AAAA (line 12) | AAAA = "AAAA"
constant CNAME (line 13) | CNAME = "CNAME"
constant TXT (line 14) | TXT = "TXT"
constant INSERT (line 16) | INSERT = "insert"
constant UPDATE (line 17) | UPDATE = "update"
constant DELETE (line 18) | DELETE = "delete"
FILE: domain/domain.go
type Domain (line 22) | type Domain struct
method Locked (line 43) | func (d *Domain) Locked() bool {
method Copy (line 48) | func (d *Domain) Copy() *Domain {
method Json (line 66) | func (d *Domain) Json() {
method Validate (line 80) | func (d *Domain) Validate(db *database.Database) (
method PreCommit (line 146) | func (d *Domain) PreCommit() {
method CommitRecords (line 150) | func (d *Domain) CommitRecords(db *database.Database) (err error) {
method CommitRecordsSilent (line 159) | func (d *Domain) CommitRecordsSilent(db *database.Database) (err error) {
method commitRecords (line 168) | func (d *Domain) commitRecords(db *database.Database,
method syncBatches (line 288) | func (d *Domain) syncBatches(db *database.Database, secr *secret.Secret,
method asyncBatches (line 306) | func (d *Domain) asyncBatches(db *database.Database, secr *secret.Secret,
method UpdateRecords (line 349) | func (d *Domain) UpdateRecords(db *database.Database, secr *secret.Sec...
method MergeRecords (line 443) | func (d *Domain) MergeRecords(deployId bson.ObjectID,
method Commit (line 507) | func (d *Domain) Commit(db *database.Database) (err error) {
method CommitFields (line 518) | func (d *Domain) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 531) | func (d *Domain) Insert(db *database.Database) (err error) {
method GetDnsService (line 550) | func (d *Domain) GetDnsService(db *database.Database) (
method preloadRecords (line 573) | func (d *Domain) preloadRecords(recs []*Record) {
method LoadRecords (line 581) | func (d *Domain) LoadRecords(db *database.Database,
type Completion (line 37) | type Completion struct
FILE: domain/record.go
type Record (line 19) | type Record struct
method Priority (line 32) | func (r *Record) Priority() int {
method IsDeleted (line 45) | func (r *Record) IsDeleted() bool {
method Copy (line 49) | func (r *Record) Copy() *Record {
method Validate (line 54) | func (r *Record) Validate(db *database.Database) (
method Commit (line 126) | func (r *Record) Commit(db *database.Database) (err error) {
method CommitFields (line 137) | func (r *Record) CommitFields(db *database.Database, fields set.Set) (
method Remove (line 150) | func (r *Record) Remove(db *database.Database) (err error) {
method Insert (line 185) | func (r *Record) Insert(db *database.Database) (err error) {
FILE: domain/sort.go
type Records (line 7) | type Records
method Len (line 9) | func (r Records) Len() int {
method Swap (line 13) | func (r Records) Swap(i, j int) {
method Less (line 17) | func (r Records) Less(i, j int) bool {
FILE: domain/utils.go
function Refresh (line 13) | func Refresh(db *database.Database, domnId bson.ObjectID) {
function Get (line 72) | func Get(db *database.Database, domnId bson.ObjectID) (
function GetOrg (line 86) | func GetOrg(db *database.Database, orgId, domnId bson.ObjectID) (
function GetOne (line 104) | func GetOne(db *database.Database, query *bson.M) (domn *Domain, err err...
function ExistsOrg (line 117) | func ExistsOrg(db *database.Database, orgId, domnId bson.ObjectID) (
function GetAll (line 138) | func GetAll(db *database.Database, query *bson.M) (
function GetLoadedAllIds (line 171) | func GetLoadedAllIds(db *database.Database, domnIds []bson.ObjectID) (
function PreloadedRecords (line 237) | func PreloadedRecords(domns []*Domain, recs []*Record) []*Domain {
function GetAllName (line 250) | func GetAllName(db *database.Database, query *bson.M) (
function GetRecordAll (line 291) | func GetRecordAll(db *database.Database, query *bson.M) (
function Lock (line 324) | func Lock(db *database.Database, domnId bson.ObjectID) (
function Relock (line 363) | func Relock(db *database.Database, domnId,
function Unlock (line 388) | func Unlock(db *database.Database, domnId,
function Remove (line 416) | func Remove(db *database.Database, domnId bson.ObjectID) (err error) {
function RemoveOrg (line 435) | func RemoveOrg(db *database.Database, orgId, domnId bson.ObjectID) (
function RemoveMulti (line 457) | func RemoveMulti(db *database.Database, domnIds []bson.ObjectID) (err er...
function RemoveMultiOrg (line 473) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: drive/drive.go
type Device (line 14) | type Device struct
FILE: drive/utils.go
function GetDevices (line 13) | func GetDevices() (devices []*Device, err error) {
function GetDriveHashId (line 45) | func GetDriveHashId(id string) string {
FILE: engine/bash.go
constant shellEnvExport (line 17) | shellEnvExport = `
type BashEngine (line 25) | type BashEngine struct
method Init (line 35) | func (b *BashEngine) Init(strt *Engine) (err error) {
method streamOut (line 55) | func (b *BashEngine) streamOut(reader io.Reader) (env []string) {
method streamErr (line 81) | func (b *BashEngine) streamErr(reader io.Reader) {
method Run (line 107) | func (b *BashEngine) Run(block string) (err error) {
FILE: engine/constants.go
constant QueueSize (line 4) | QueueSize = 256
FILE: engine/engine.go
type Engine (line 16) | type Engine struct
method UpdateEnv (line 29) | func (e *Engine) UpdateEnv(key, val string) {
method UpdateCwd (line 33) | func (e *Engine) UpdateCwd(cwd string) {
method ProcessOutput (line 37) | func (e *Engine) ProcessOutput(output string) {
method GetEnv (line 43) | func (e *Engine) GetEnv() map[string]string {
method GetCwd (line 47) | func (e *Engine) GetCwd() string {
method GetEnviron (line 51) | func (e *Engine) GetEnviron() (env []string) {
method Init (line 68) | func (e *Engine) Init() (err error) {
method StartRunner (line 103) | func (e *Engine) StartRunner() {
method getBlocks (line 107) | func (e *Engine) getBlocks() (blocks []*Block) {
method UpdateSpec (line 120) | func (e *Engine) UpdateSpec(data string) (err error) {
method runner (line 131) | func (e *Engine) runner() {
method Run (line 153) | func (e *Engine) Run(phase string, blocks []*Block) (fatal bool, err e...
method runBlock (line 202) | func (e *Engine) runBlock(blockType, block string) (err error) {
method Queue (line 219) | func (e *Engine) Queue(data string) {
FILE: engine/parser.go
type Block (line 8) | type Block struct
constant Initial (line 16) | Initial = "initial"
constant Reboot (line 17) | Reboot = "reboot"
constant Reload (line 18) | Reload = "reload"
constant Image (line 19) | Image = "image"
function Parse (line 26) | func Parse(data string) (blocks []*Block, err error) {
function parseCodeBlockHeader (line 75) | func parseCodeBlockHeader(input string) (language string,
FILE: engine/python.go
constant pyEngine (line 20) | pyEngine = `#!/usr/bin/env python3
type pythonData (line 68) | type pythonData struct
type PythonEngine (line 74) | type PythonEngine struct
method Init (line 89) | func (p *PythonEngine) Init(strt *Engine) (err error) {
method start (line 95) | func (p *PythonEngine) start() (err error) {
method flushOutput (line 144) | func (p *PythonEngine) flushOutput() {
method copyOutput (line 154) | func (p *PythonEngine) copyOutput(src io.ReadCloser) {
method wait (line 220) | func (p *PythonEngine) wait() {
method updateEnv (line 243) | func (p *PythonEngine) updateEnv() (err error) {
method updateCwd (line 275) | func (p *PythonEngine) updateCwd() (err error) {
method run (line 307) | func (p *PythonEngine) run(code string) (err error) {
method Exit (line 339) | func (p *PythonEngine) Exit() (err error) {
method Run (line 375) | func (p *PythonEngine) Run(code string) (err error) {
FILE: errortypes/errortypes.go
type UnknownError (line 7) | type UnknownError struct
type NotFoundError (line 11) | type NotFoundError struct
type ReadError (line 15) | type ReadError struct
type WriteError (line 19) | type WriteError struct
type ParseError (line 23) | type ParseError struct
type AuthenticationError (line 27) | type AuthenticationError struct
type VerificationError (line 31) | type VerificationError struct
type ApiError (line 35) | type ApiError struct
type DatabaseError (line 39) | type DatabaseError struct
type RequestError (line 43) | type RequestError struct
type ConnectionError (line 47) | type ConnectionError struct
type TimeoutError (line 51) | type TimeoutError struct
type ExecError (line 55) | type ExecError struct
type NetworkError (line 59) | type NetworkError struct
type TypeError (line 63) | type TypeError struct
type ErrorData (line 67) | type ErrorData struct
method GetError (line 72) | func (e *ErrorData) GetError() (err error) {
function GetErrorMessage (line 79) | func GetErrorMessage(err error) string {
FILE: eval/constants.go
type Equal (line 7) | type Equal struct
type NotEqual (line 8) | type NotEqual struct
type Less (line 9) | type Less struct
type LessEqual (line 10) | type LessEqual struct
type Greater (line 11) | type Greater struct
type GreaterEqual (line 12) | type GreaterEqual struct
type If (line 13) | type If struct
type And (line 14) | type And struct
type Or (line 15) | type Or struct
type For (line 16) | type For struct
type Then (line 17) | type Then struct
constant StatementMaxLength (line 20) | StatementMaxLength = 1024
constant StatementMaxParts (line 21) | StatementMaxParts = 30
FILE: eval/errortypes.go
type EvalError (line 12) | type EvalError struct
function NewEvalError (line 20) | func NewEvalError(statement string, index, errorIndex int,
FILE: eval/eval.go
type Data (line 9) | type Data
type Parser (line 11) | type Parser struct
method parseRef (line 18) | func (p *Parser) parseRef(ref string, pos int) (val interface{}, err e...
method parseComp (line 150) | func (p *Parser) parseComp(left, right, comp interface{}) bool {
method Eval (line 231) | func (p *Parser) Eval() (resp string, threshold int, err error) {
function Eval (line 535) | func Eval(data Data, statement string) (resp string,
FILE: eval/utils.go
function Validate (line 8) | func Validate(statement string) (err error) {
FILE: event/event.go
type Event (line 21) | type Event struct
type EventPublish (line 28) | type EventPublish struct
type CustomEvent (line 35) | type CustomEvent interface
type Dispatch (line 40) | type Dispatch struct
function getCursorId (line 44) | func getCursorId(db *database.Database, coll *database.Collection,
function getCursorIdRetry (line 97) | func getCursorIdRetry(channels []string) bson.ObjectID {
function Publish (line 124) | func Publish(db *database.Database, channel string, data interface{}) (
function PublishDispatch (line 145) | func PublishDispatch(db *database.Database, typ string) (
function Subscribe (line 160) | func Subscribe(channels []string, duration time.Duration,
function SubscribeType (line 306) | func SubscribeType(channels []string, duration time.Duration,
function Register (line 449) | func Register(channel string, callback func(*EventPublish)) {
function subscribe (line 459) | func subscribe(channels []string) {
function init (line 474) | func init() {
FILE: event/listener.go
type Listener (line 17) | type Listener struct
method Listen (line 25) | func (l *Listener) Listen() chan *Event {
method Close (line 29) | func (l *Listener) Close() {
method sub (line 36) | func (l *Listener) sub(cursorId bson.ObjectID) {
method init (line 188) | func (l *Listener) init() (err error) {
function SubscribeListener (line 210) | func SubscribeListener(db *database.Database, channels []string) (
FILE: event/socket.go
type WebSocket (line 26) | type WebSocket struct
method Close (line 34) | func (w *WebSocket) Close() {
function WebSocketsStop (line 62) | func WebSocketsStop() {
FILE: features/qemu.go
constant Libexec (line 24) | Libexec = "/usr/libexec/qemu-kvm"
constant System (line 25) | System = "/usr/bin/qemu-system-x86_64"
type version (line 28) | type version struct
function GetQemuPath (line 34) | func GetQemuPath() (path string, err error) {
function GetQemuVersion (line 48) | func GetQemuVersion() (major, minor, patch int, err error) {
function GetKernelVersion (line 121) | func GetKernelVersion() (major, minor, patch int, err error) {
function GetUringSupport (line 195) | func GetUringSupport() (supported bool, err error) {
function GetExtUringSupport (line 264) | func GetExtUringSupport() (supported bool, err error) {
function GetMemoryBackendSupport (line 281) | func GetMemoryBackendSupport() (supported bool, err error) {
function GetRunWithSupport (line 294) | func GetRunWithSupport() (supported bool, err error) {
FILE: features/systemd.go
function GetSystemdVersion (line 10) | func GetSystemdVersion() (ver int) {
function HasSystemdNamespace (line 39) | func HasSystemdNamespace() bool {
FILE: finder/constants.go
constant DomainKind (line 4) | DomainKind = "domain"
constant VpcKind (line 5) | VpcKind = "vpc"
constant SubnetKind (line 6) | SubnetKind = "subnet"
constant DatacenterKind (line 7) | DatacenterKind = "datacenter"
constant NodeKind (line 8) | NodeKind = "node"
constant PoolKind (line 9) | PoolKind = "pool"
constant ZoneKind (line 10) | ZoneKind = "zone"
constant ShapeKind (line 11) | ShapeKind = "shape"
constant DiskKind (line 12) | DiskKind = "disk"
constant ImageKind (line 13) | ImageKind = "image"
constant BuildKind (line 14) | BuildKind = "build"
constant InstanceKind (line 15) | InstanceKind = "instance"
constant FirewallKind (line 16) | FirewallKind = "firewall"
constant PlanKind (line 17) | PlanKind = "plan"
constant CertificateKind (line 18) | CertificateKind = "certificate"
constant SecretKind (line 19) | SecretKind = "secret"
constant PodKind (line 20) | PodKind = "pod"
constant UnitKind (line 21) | UnitKind = "unit"
constant JournalKind (line 22) | JournalKind = "journal"
FILE: finder/resources.go
type Resources (line 27) | type Resources struct
method Find (line 52) | func (r *Resources) Find(db *database.Database, token string) (
type PodBase (line 393) | type PodBase struct
type UnitBase (line 399) | type UnitBase struct
function GetPodBase (line 406) | func GetPodBase(db *database.Database, query *bson.M) (
function GetUnitBase (line 421) | func GetUnitBase(db *database.Database, orgId bson.ObjectID,
FILE: firewall/constants.go
constant All (line 6) | All = "all"
constant Icmp (line 7) | Icmp = "icmp"
constant Tcp (line 8) | Tcp = "tcp"
constant Udp (line 9) | Udp = "udp"
constant Multicast (line 10) | Multicast = "multicast"
constant Broadcast (line 11) | Broadcast = "broadcast"
FILE: firewall/firewall.go
type Rule (line 17) | type Rule struct
method SetName (line 31) | func (r *Rule) SetName(ipv6 bool) (name string) {
type Mapping (line 23) | type Mapping struct
type Firewall (line 83) | type Firewall struct
method Validate (line 92) | func (f *Firewall) Validate(db *database.Database) (
method Commit (line 203) | func (f *Firewall) Commit(db *database.Database) (err error) {
method CommitFields (line 214) | func (f *Firewall) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 227) | func (f *Firewall) Insert(db *database.Database) (err error) {
FILE: firewall/spec.go
function GetSpecRules (line 18) | func GetSpecRules(instances []*instance.Instance,
function GetSpecRulesSlow (line 156) | func GetSpecRulesSlow(db *database.Database,
FILE: firewall/utils.go
function Get (line 21) | func Get(db *database.Database, fireId bson.ObjectID) (
function GetOrg (line 35) | func GetOrg(db *database.Database, orgId, fireId bson.ObjectID) (
function GetAll (line 53) | func GetAll(db *database.Database, query *bson.M) (
function GetRoles (line 86) | func GetRoles(db *database.Database, roles []string) (
function GetMapRoles (line 127) | func GetMapRoles(db *database.Database, roles []string) (
function GetOrgMapRoles (line 170) | func GetOrgMapRoles(db *database.Database, orgId bson.ObjectID) (
function GetOrgRoles (line 211) | func GetOrgRoles(db *database.Database, orgId bson.ObjectID,
function GetAllPaged (line 252) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 318) | func Remove(db *database.Database, fireId bson.ObjectID) (err error) {
function RemoveOrg (line 337) | func RemoveOrg(db *database.Database, orgId, fireId bson.ObjectID) (
function RemoveMulti (line 359) | func RemoveMulti(db *database.Database, fireIds []bson.ObjectID) (
function RemoveMultiOrg (line 377) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
function MergeIngress (line 396) | func MergeIngress(fires []*Firewall) (rules []*Rule) {
function GetAllIngress (line 438) | func GetAllIngress(db *database.Database, nodeSelf *node.Node,
function GetAllIngressPreloaded (line 539) | func GetAllIngressPreloaded(nodeSelf *node.Node,
FILE: geo/geo.go
type Geo (line 22) | type Geo struct
type geoData (line 37) | type geoData struct
function get (line 42) | func get(addr string) (ge *Geo, err error) {
function Get (line 100) | func Get(db *database.Database, addr string) (ge *Geo, err error) {
FILE: guest/guest.go
type Command (line 13) | type Command struct
type Response (line 18) | type Response struct
FILE: guest/power.go
function Shutdown (line 15) | func Shutdown(vmId bson.ObjectID) (err error) {
FILE: hnetwork/hnetwork.go
type IptablesRule (line 22) | type IptablesRule struct
method Add (line 27) | func (h *IptablesRule) Add() (err error) {
method Remove (line 64) | func (h *IptablesRule) Remove() (err error) {
function loadIptablesNat (line 98) | func loadIptablesNat() (rules []*IptablesRule, err error) {
function removeNetwork (line 167) | func removeNetwork(stat *state.State) (err error) {
function ApplyState (line 182) | func ApplyState(stat *state.State) (err error) {
FILE: hnetwork/utils.go
function create (line 12) | func create() (err error) {
function getAddr (line 32) | func getAddr() (addr string, err error) {
function setAddr (line 46) | func setAddr(addr string) (err error) {
function clearAddr (line 77) | func clearAddr() (err error) {
FILE: hugepages/hugepages.go
function HugepageSize (line 14) | func HugepageSize() (count int, size uint64, err error) {
function UpdateHugepagesSize (line 36) | func UpdateHugepagesSize() (err error) {
FILE: image/constants.go
constant Uefi (line 9) | Uefi = "uefi"
constant Bios (line 10) | Bios = "bios"
constant Unknown (line 11) | Unknown = "unknown"
constant Linux (line 13) | Linux = "linux"
constant LinuxLegacy (line 14) | LinuxLegacy = "linux_legacy"
constant LinuxUnsigned (line 15) | LinuxUnsigned = "linux_unsigned"
constant Bsd (line 16) | Bsd = "bsd"
constant RedHat (line 18) | RedHat = "redhat"
constant Fedora (line 19) | Fedora = "fedora"
constant Ubuntu (line 20) | Ubuntu = "ubuntu"
constant AlmaLinux8 (line 22) | AlmaLinux8 = "almalinux8"
constant AlmaLinux9 (line 23) | AlmaLinux9 = "almalinux9"
constant AlmaLinux10 (line 24) | AlmaLinux10 = "almalinux10"
constant AlmaLinux11 (line 25) | AlmaLinux11 = "almalinux11"
constant AlmaLinux12 (line 26) | AlmaLinux12 = "almalinux12"
constant AlmaLinux13 (line 27) | AlmaLinux13 = "almalinux13"
constant AlmaLinux14 (line 28) | AlmaLinux14 = "almalinux14"
constant AlmaLinux15 (line 29) | AlmaLinux15 = "almalinux15"
constant AlmaLinux16 (line 30) | AlmaLinux16 = "almalinux16"
constant AlpineLinux (line 31) | AlpineLinux = "alpinelinux"
constant ArchLinux (line 32) | ArchLinux = "archlinux"
constant Fedora42 (line 33) | Fedora42 = "fedora42"
constant Fedora43 (line 34) | Fedora43 = "fedora43"
constant Fedora44 (line 35) | Fedora44 = "fedora44"
constant Fedora45 (line 36) | Fedora45 = "fedora45"
constant Fedora46 (line 37) | Fedora46 = "fedora46"
constant Fedora47 (line 38) | Fedora47 = "fedora47"
constant Fedora48 (line 39) | Fedora48 = "fedora48"
constant Fedora49 (line 40) | Fedora49 = "fedora49"
constant Fedora50 (line 41) | Fedora50 = "fedora50"
constant Fedora51 (line 42) | Fedora51 = "fedora51"
constant Fedora52 (line 43) | Fedora52 = "fedora52"
constant Fedora53 (line 44) | Fedora53 = "fedora53"
constant Fedora54 (line 45) | Fedora54 = "fedora54"
constant Fedora55 (line 46) | Fedora55 = "fedora55"
constant Fedora56 (line 47) | Fedora56 = "fedora56"
constant Fedora57 (line 48) | Fedora57 = "fedora57"
constant Fedora58 (line 49) | Fedora58 = "fedora58"
constant Fedora59 (line 50) | Fedora59 = "fedora59"
constant Fedora60 (line 51) | Fedora60 = "fedora60"
constant Fedora61 (line 52) | Fedora61 = "fedora61"
constant Fedora62 (line 53) | Fedora62 = "fedora62"
constant FreeBSD (line 54) | FreeBSD = "freebsd"
constant OracleLinux7 (line 55) | OracleLinux7 = "oraclelinux7"
constant OracleLinux8 (line 56) | OracleLinux8 = "oraclelinux8"
constant OracleLinux9 (line 57) | OracleLinux9 = "oraclelinux9"
constant OracleLinux10 (line 58) | OracleLinux10 = "oraclelinux10"
constant OracleLinux11 (line 59) | OracleLinux11 = "oraclelinux11"
constant OracleLinux12 (line 60) | OracleLinux12 = "oraclelinux12"
constant OracleLinux13 (line 61) | OracleLinux13 = "oraclelinux13"
constant OracleLinux14 (line 62) | OracleLinux14 = "oraclelinux14"
constant OracleLinux15 (line 63) | OracleLinux15 = "oraclelinux15"
constant OracleLinux16 (line 64) | OracleLinux16 = "oraclelinux16"
constant RockyLinux8 (line 65) | RockyLinux8 = "rockylinux8"
constant RockyLinux9 (line 66) | RockyLinux9 = "rockylinux9"
constant RockyLinux10 (line 67) | RockyLinux10 = "rockylinux10"
constant RockyLinux11 (line 68) | RockyLinux11 = "rockylinux11"
constant RockyLinux12 (line 69) | RockyLinux12 = "rockylinux12"
constant RockyLinux13 (line 70) | RockyLinux13 = "rockylinux13"
constant RockyLinux14 (line 71) | RockyLinux14 = "rockylinux14"
constant RockyLinux15 (line 72) | RockyLinux15 = "rockylinux15"
constant RockyLinux16 (line 73) | RockyLinux16 = "rockylinux16"
constant Ubuntu2404 (line 74) | Ubuntu2404 = "ubuntu2404"
constant Ubuntu2604 (line 75) | Ubuntu2604 = "ubuntu2604"
constant Ubuntu2804 (line 76) | Ubuntu2804 = "ubuntu2804"
constant Ubuntu3004 (line 77) | Ubuntu3004 = "ubuntu3004"
constant Ubuntu3204 (line 78) | Ubuntu3204 = "ubuntu3204"
constant Ubuntu3404 (line 79) | Ubuntu3404 = "ubuntu3404"
constant Ubuntu3604 (line 80) | Ubuntu3604 = "ubuntu3604"
constant Ubuntu3804 (line 81) | Ubuntu3804 = "ubuntu3804"
constant Ubuntu4004 (line 82) | Ubuntu4004 = "ubuntu4004"
constant Ubuntu4204 (line 83) | Ubuntu4204 = "ubuntu4204"
constant Ubuntu4404 (line 84) | Ubuntu4404 = "ubuntu4404"
FILE: image/errortypes.go
type LostImageError (line 7) | type LostImageError struct
FILE: image/image.go
type Image (line 17) | type Image struct
method Validate (line 54) | func (i *Image) Validate(db *database.Database) (
method Parse (line 85) | func (i *Image) Parse() {
method GetSystemType (line 95) | func (i *Image) GetSystemType() string {
method GetSystemKind (line 124) | func (i *Image) GetSystemKind() string {
method Json (line 161) | func (i *Image) Json() {
method Commit (line 165) | func (i *Image) Commit(db *database.Database) (err error) {
method CommitFields (line 176) | func (i *Image) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 189) | func (i *Image) Insert(db *database.Database) (err error) {
method Upsert (line 201) | func (i *Image) Upsert(db *database.Database) (err error) {
method Sync (line 245) | func (i *Image) Sync(db *database.Database) (err error) {
method Remove (line 340) | func (i *Image) Remove(db *database.Database) (err error) {
type Completion (line 40) | type Completion struct
FILE: image/sort.go
type ImagesSort (line 7) | type ImagesSort
method Len (line 9) | func (x ImagesSort) Len() int {
method Swap (line 13) | func (x ImagesSort) Swap(i, j int) {
method Less (line 17) | func (x ImagesSort) Less(i, j int) bool {
type CompletionsSort (line 21) | type CompletionsSort
method Len (line 23) | func (x CompletionsSort) Len() int {
method Swap (line 27) | func (x CompletionsSort) Swap(i, j int) {
method Less (line 31) | func (x CompletionsSort) Less(i, j int) bool {
FILE: image/utils.go
function GetEtag (line 25) | func GetEtag(info minio.ObjectInfo) string {
function ParseImageName (line 36) | func ParseImageName(key string) (name, release, build string) {
function Get (line 81) | func Get(db *database.Database, imgId bson.ObjectID) (
function GetKey (line 95) | func GetKey(db *database.Database, storeId bson.ObjectID, key string) (
function GetOrg (line 113) | func GetOrg(db *database.Database, orgId, imgId bson.ObjectID) (
function GetOrgPublic (line 131) | func GetOrgPublic(db *database.Database, orgId, imgId bson.ObjectID) (
function GetOne (line 149) | func GetOne(db *database.Database, query *bson.M) (img *Image, err error) {
function Distinct (line 162) | func Distinct(db *database.Database, storeId bson.ObjectID) (
function ExistsOrg (line 179) | func ExistsOrg(db *database.Database, orgId, imgId bson.ObjectID) (
function GetAll (line 200) | func GetAll(db *database.Database, query *bson.M) (
function GetAllCompletion (line 233) | func GetAllCompletion(db *database.Database, query *bson.M) (
function GetAllPaged (line 283) | func GetAllPaged(db *database.Database, query *bson.M, page, pageCount i...
function GetAllNames (line 344) | func GetAllNames(db *database.Database, query *bson.M) (
function GetAllKeys (line 390) | func GetAllKeys(db *database.Database) (keys set.Set, err error) {
function Remove (line 430) | func Remove(db *database.Database, imgId bson.ObjectID) (err error) {
FILE: imds/config.go
function BuildConfig (line 25) | func BuildConfig(inst *instance.Instance, virt *vm.VirtualMachine,
function SetConfigs (line 54) | func SetConfigs(cnfs map[bson.ObjectID]*types.Config) {
function GetConfigs (line 60) | func GetConfigs() (
FILE: imds/imds.go
constant counterMax (line 41) | counterMax = 2000000000
function mergeUpdateDetails (line 44) | func mergeUpdateDetails(db *database.Database, instId bson.ObjectID,
function Sync (line 83) | func Sync(db *database.Database, namespace string,
function Pull (line 479) | func Pull(db *database.Database, instId, deplyId bson.ObjectID,
function State (line 671) | func State(db *database.Database, instId bson.ObjectID,
FILE: imds/resource/resource.go
function Query (line 11) | func Query(resrc string, keys ...string) (val string, err error) {
FILE: imds/resource/utils.go
function selector (line 15) | func selector(v interface{}, key string, isJson bool) (val string, err e...
function jsonValString (line 90) | func jsonValString(value any) string {
function selectString (line 110) | func selectString(obj interface{}) string {
FILE: imds/server/constants/constants.go
constant Version (line 8) | Version = "1.0.3229.20"
constant ConfRefresh (line 9) | ConfRefresh = 500 * time.Millisecond
FILE: imds/server/errortypes/errortypes.go
type UnknownError (line 7) | type UnknownError struct
type NotFoundError (line 11) | type NotFoundError struct
type ReadError (line 15) | type ReadError struct
type WriteError (line 19) | type WriteError struct
type ParseError (line 23) | type ParseError struct
type AuthenticationError (line 27) | type AuthenticationError struct
type VerificationError (line 31) | type VerificationError struct
type ApiError (line 35) | type ApiError struct
type DatabaseError (line 39) | type DatabaseError struct
type RequestError (line 43) | type RequestError struct
type ConnectionError (line 47) | type ConnectionError struct
type TimeoutError (line 51) | type TimeoutError struct
type ExecError (line 55) | type ExecError struct
type NetworkError (line 59) | type NetworkError struct
type TypeError (line 63) | type TypeError struct
type ErrorData (line 67) | type ErrorData struct
FILE: imds/server/handlers/certificate.go
function certificatesGet (line 8) | func certificatesGet(c *gin.Context) {
FILE: imds/server/handlers/dhcp.go
function dhcpPut (line 12) | func dhcpPut(c *gin.Context) {
FILE: imds/server/handlers/handlers.go
type AuthenticationError (line 14) | type AuthenticationError struct
function Recovery (line 19) | func Recovery(c *gin.Context) {
function Errors (line 35) | func Errors(c *gin.Context) {
function AuthVirt (line 44) | func AuthVirt(c *gin.Context) {
function AuthDhcp (line 75) | func AuthDhcp(c *gin.Context) {
function AuthHost (line 94) | func AuthHost(c *gin.Context) {
function RegisterVirt (line 113) | func RegisterVirt(engine *gin.Engine) {
function RegisterHost (line 139) | func RegisterHost(engine *gin.Engine) {
FILE: imds/server/handlers/instance.go
function instanceGet (line 8) | func instanceGet(c *gin.Context) {
FILE: imds/server/handlers/node.go
function nodeGet (line 8) | func nodeGet(c *gin.Context) {
FILE: imds/server/handlers/query.go
function queryGet (line 8) | func queryGet(c *gin.Context) {
FILE: imds/server/handlers/secret.go
function secretsGet (line 8) | func secretsGet(c *gin.Context) {
FILE: imds/server/handlers/sync.go
type syncRespData (line 23) | type syncRespData struct
function syncPut (line 29) | func syncPut(c *gin.Context) {
function hostSyncPut (line 83) | func hostSyncPut(c *gin.Context) {
function hostSyncGet (line 115) | func hostSyncGet(c *gin.Context) {
function hostStateGet (line 130) | func hostStateGet(c *gin.Context) {
FILE: imds/server/handlers/vpc.go
function vpcGet (line 8) | func vpcGet(c *gin.Context) {
function subnetGet (line 12) | func subnetGet(c *gin.Context) {
FILE: imds/server/router/router.go
type Router (line 21) | type Router struct
method Run (line 27) | func (r *Router) Run() (err error) {
method Shutdown (line 121) | func (r *Router) Shutdown() {
method Init (line 141) | func (r *Router) Init() {
FILE: imds/server/server.go
function Main (line 15) | func Main() (err error) {
FILE: imds/server/state/state.go
type Store (line 15) | type Store struct
method AppendOutput (line 22) | func (s *Store) AppendOutput(entry *types.Entry) {
method GetOutput (line 29) | func (s *Store) GetOutput() (entries []*types.Entry) {
method AppendJournalOutput (line 40) | func (s *Store) AppendJournalOutput(key string, entry *types.Entry) {
method GetJournals (line 55) | func (s *Store) GetJournals() (journals map[string][]*types.Entry) {
function Init (line 91) | func Init() (err error) {
FILE: imds/server/utils/files.go
function Chmod (line 16) | func Chmod(pth string, mode os.FileMode) (err error) {
function Exists (line 28) | func Exists(pth string) (exists bool, err error) {
function ExistsDir (line 46) | func ExistsDir(pth string) (exists bool, err error) {
function ExistsFile (line 64) | func ExistsFile(pth string) (exists bool, err error) {
function ExistsMkdir (line 82) | func ExistsMkdir(pth string, perm os.FileMode) (err error) {
function ExistsRemove (line 101) | func ExistsRemove(pth string) (err error) {
function Remove (line 120) | func Remove(path string) (err error) {
function RemoveAll (line 139) | func RemoveAll(path string) (err error) {
function ContainsDir (line 158) | func ContainsDir(pth string) (hasDir bool, err error) {
function Open (line 182) | func Open(path string, perm os.FileMode) (file *os.File, err error) {
function Read (line 194) | func Read(path string) (data string, err error) {
function ReadLines (line 207) | func ReadLines(path string) (lines []string, err error) {
function Write (line 238) | func Write(path string, data string, perm os.FileMode) (err error) {
function Create (line 264) | func Create(path string, perm os.FileMode) (file *os.File, err error) {
function CreateWrite (line 276) | func CreateWrite(path string, data string, perm os.FileMode) (err error) {
FILE: imds/server/utils/misc.go
function StringsContains (line 3) | func StringsContains(val []string, str string) bool {
FILE: imds/server/utils/request.go
function StripPort (line 7) | func StripPort(hostport string) string {
FILE: imds/systemd.go
constant systemdNamespaceTemplate (line 20) | systemdNamespaceTemplate = `[Unit]
constant systemdTemplate (line 43) | systemdTemplate = `[Unit]
function WriteService (line 65) | func WriteService(vmId bson.ObjectID,
function Start (line 113) | func Start(db *database.Database, virt *vm.VirtualMachine) (err error) {
function Restart (line 145) | func Restart(instId bson.ObjectID) (err error) {
function Stop (line 153) | func Stop(virt *vm.VirtualMachine) (err error) {
FILE: imds/types/certificate.go
type Certificate (line 8) | type Certificate struct
function NewCertificates (line 16) | func NewCertificates(certs []*certificate.Certificate) []*Certificate {
FILE: imds/types/config.go
type Config (line 9) | type Config struct
method ComputeHash (line 26) | func (c *Config) ComputeHash() (err error) {
FILE: imds/types/constants.go
constant Initializing (line 4) | Initializing = "initializing"
constant ReloadingClean (line 5) | ReloadingClean = "reloading_clean"
constant ReloadingFault (line 6) | ReloadingFault = "reloading_fault"
constant Running (line 7) | Running = "running"
constant Fault (line 8) | Fault = "fault"
constant Offline (line 9) | Offline = "offline"
constant Imaged (line 10) | Imaged = "imaged"
FILE: imds/types/domain.go
type Domain (line 7) | type Domain struct
FILE: imds/types/instance.go
type Instance (line 10) | type Instance struct
function NewInstance (line 59) | func NewInstance(inst *instance.Instance) *Instance {
FILE: imds/types/journal.go
type Journal (line 7) | type Journal struct
function NewJournals (line 15) | func NewJournals(spc *spec.Spec) []*Journal {
FILE: imds/types/node.go
type Node (line 8) | type Node struct
function NewNode (line 15) | func NewNode(nde *node.Node) *Node {
FILE: imds/types/pod.go
type Pod (line 10) | type Pod struct
type Unit (line 16) | type Unit struct
function NewPods (line 44) | func NewPods(pods []*pod.Pod, podUnitsMap map[bson.ObjectID][]*unit.Unit,
FILE: imds/types/secret.go
type Secret (line 8) | type Secret struct
function NewSecrets (line 20) | func NewSecrets(secrs []*secret.Secret) []*Secret {
FILE: imds/types/state.go
type State (line 10) | type State struct
method Final (line 29) | func (s *State) Final() bool {
method Copy (line 36) | func (s *State) Copy() *State {
type Entry (line 55) | type Entry struct
constant Error (line 62) | Error = 3
constant Info (line 63) | Info = 5
FILE: imds/types/vpc.go
type Vpc (line 10) | type Vpc struct
type Subnet (line 20) | type Subnet struct
method String (line 26) | func (s *Subnet) String() string {
type Route (line 30) | type Route struct
method String (line 35) | func (r *Route) String() string {
function NewSubnet (line 39) | func NewSubnet(subnet *vpc.Subnet) *Subnet {
function NewRoute (line 50) | func NewRoute(subnet *vpc.Route) *Route {
function NewVpc (line 60) | func NewVpc(vpc *vpc.Vpc) *Vpc {
FILE: info/instance.go
function NewInstance (line 16) | func NewInstance(stat *state.State, inst *instance.Instance) (
FILE: instance/constants.go
constant Starting (line 8) | Starting = "starting"
constant Running (line 9) | Running = "running"
constant Stopped (line 10) | Stopped = "stopped"
constant Failed (line 11) | Failed = "failed"
constant Updating (line 12) | Updating = "updating"
constant Provisioning (line 13) | Provisioning = "provisioning"
constant Bridge (line 14) | Bridge = "bridge"
constant Vxlan (line 15) | Vxlan = "vxlan"
constant Start (line 17) | Start = "start"
constant Stop (line 18) | Stop = "stop"
constant Cleanup (line 19) | Cleanup = "cleanup"
constant Restart (line 20) | Restart = "restart"
constant Destroy (line 21) | Destroy = "destroy"
constant Linux (line 22) | Linux = "linux"
constant LinuxLegacy (line 23) | LinuxLegacy = "linux_legacy"
constant BSD (line 24) | BSD = "bsd"
constant AlpineLinux (line 26) | AlpineLinux = "alpinelinux"
constant ArchLinux (line 27) | ArchLinux = "archlinux"
constant RedHat (line 28) | RedHat = "redhat"
constant Fedora (line 29) | Fedora = "fedora"
constant Ubuntu (line 30) | Ubuntu = "ubuntu"
constant FreeBSD (line 31) | FreeBSD = "freebsd"
constant HostPath (line 33) | HostPath = "host_path"
FILE: instance/errortypes.go
type VncDialError (line 7) | type VncDialError struct
FILE: instance/instance.go
type Instance (line 42) | type Instance struct
method GenerateId (line 186) | func (i *Instance) GenerateId() (err error) {
method Validate (line 200) | func (i *Instance) Validate(db *database.Database) (
method GenerateUnixId (line 634) | func (i *Instance) GenerateUnixId() {
method InitUnixId (line 638) | func (i *Instance) InitUnixId(db *database.Database) (err error) {
method GenerateSpicePort (line 653) | func (i *Instance) GenerateSpicePort() {
method InitSpicePort (line 658) | func (i *Instance) InitSpicePort(db *database.Database) (err error) {
method GenerateVncDisplay (line 690) | func (i *Instance) GenerateVncDisplay() {
method InitVncDisplay (line 696) | func (i *Instance) InitVncDisplay(db *database.Database) (err error) {
method Format (line 728) | func (i *Instance) Format() {
method Json (line 731) | func (i *Instance) Json(short bool) {
method IsActive (line 852) | func (i *Instance) IsActive() bool {
method IsIpv6Only (line 857) | func (i *Instance) IsIpv6Only() bool {
method PreCommit (line 863) | func (i *Instance) PreCommit() {
method UpsertNodePorts (line 878) | func (i *Instance) UpsertNodePorts(newNodePorts []*nodeport.Mapping) {
method SyncNodePorts (line 929) | func (i *Instance) SyncNodePorts(db *database.Database) (err error) {
method PostCommit (line 1008) | func (i *Instance) PostCommit(db *database.Database) (
method Cleanup (line 1061) | func (i *Instance) Cleanup(db *database.Database) (err error) {
method Commit (line 1099) | func (i *Instance) Commit(db *database.Database) (err error) {
method CommitFields (line 1110) | func (i *Instance) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 1145) | func (i *Instance) Insert(db *database.Database) (err error) {
method LoadVirt (line 1179) | func (i *Instance) LoadVirt(poolsMap map[bson.ObjectID]*pool.Pool,
method Changed (line 1348) | func (i *Instance) Changed(curVirt *vm.VirtualMachine) (bool, string) {
method DiskChanged (line 1513) | func (i *Instance) DiskChanged(curVirt *vm.VirtualMachine) (
method UsbChanged (line 1552) | func (i *Instance) UsbChanged(curVirt *vm.VirtualMachine) (
method VncConnect (line 1607) | func (i *Instance) VncConnect(db *database.Database,
type Completion (line 136) | type Completion struct
type Mount (line 146) | type Mount struct
type StatusInfo (line 153) | type StatusInfo struct
type GuestData (line 158) | type GuestData struct
type Info (line 170) | type Info struct
FILE: instance/utils.go
function Get (line 17) | func Get(db *database.Database, instId bson.ObjectID) (
function GetOrg (line 31) | func GetOrg(db *database.Database, orgId, instId bson.ObjectID) (
function GetOne (line 49) | func GetOne(db *database.Database, query *bson.M) (inst *Instance, err e...
function ExistsIp (line 62) | func ExistsIp(db *database.Database, addr string) (exists bool, err erro...
function ExistsOrg (line 88) | func ExistsOrg(db *database.Database, orgId, instId bson.ObjectID) (
function GetAll (line 109) | func GetAll(db *database.Database, query *bson.M) (
function GetAllRoles (line 142) | func GetAllRoles(db *database.Database, query *bson.M) (
function GetAllVirt (line 180) | func GetAllVirt(db *database.Database, query *bson.M,
function GetAllVirtMapped (line 245) | func GetAllVirtMapped(db *database.Database, query *bson.M,
function LoadAllVirt (line 308) | func LoadAllVirt(insts []*Instance, pools []*pool.Pool,
function GetAllName (line 344) | func GetAllName(db *database.Database, query *bson.M) (
function GetAllPaged (line 380) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 446) | func Remove(db *database.Database, instId bson.ObjectID) (err error) {
function Delete (line 494) | func Delete(db *database.Database, instId bson.ObjectID) (err error) {
function DeleteOrg (line 510) | func DeleteOrg(db *database.Database, orgId, instId bson.ObjectID) (
function DeleteMulti (line 529) | func DeleteMulti(db *database.Database, instIds []bson.ObjectID) (
function DeleteMultiOrg (line 554) | func DeleteMultiOrg(db *database.Database, orgId bson.ObjectID,
function UpdateMulti (line 580) | func UpdateMulti(db *database.Database, instIds []bson.ObjectID,
function UpdateMultiOrg (line 611) | func UpdateMultiOrg(db *database.Database, orgId bson.ObjectID,
function SetAction (line 643) | func SetAction(db *database.Database, instId bson.ObjectID,
function SetDownloadProgress (line 666) | func SetDownloadProgress(db *database.Database,
FILE: interfaces/interfaces.go
function getIfaces (line 21) | func getIfaces(bridge string) (ifacesSet set.Set, err error) {
function SyncIfaces (line 36) | func SyncIfaces(vxlan bool) {
function GetExternal (line 109) | func GetExternal(virtIface string) (externalIface string) {
function HasExternal (line 149) | func HasExternal() (exists bool) {
function GetInternal (line 164) | func GetInternal(virtIface string, vxlan bool) (internalIface string) {
function GetBridges (line 208) | func GetBridges(nde *node.Node) (bridges set.Set) {
function GetBridgesInternal (line 240) | func GetBridgesInternal(nde *node.Node) (bridges set.Set) {
function GetBridgesExternal (line 251) | func GetBridgesExternal(nde *node.Node) (bridges set.Set) {
function RemoveVirtIface (line 278) | func RemoveVirtIface(virtIface string) {
FILE: ip/interface.go
type Interface (line 3) | type Interface struct
FILE: ip/ip.go
type Iface (line 20) | type Iface struct
method GetAddress (line 50) | func (iface *Iface) GetAddress() string {
method GetAddress6 (line 77) | func (iface *Iface) GetAddress6() string {
function GetIfaces (line 104) | func GetIfaces(namespace string) (ifaces []*Iface, err error) {
function GetIfacesCached (line 136) | func GetIfacesCached(namespace string) (ifacesMap map[string]*Iface, err...
function ClearIfacesCache (line 163) | func ClearIfacesCache(namespace string) {
FILE: iproute/address.go
type Address (line 12) | type Address struct
type AddressIface (line 22) | type AddressIface struct
function AddressGetIface (line 28) | func AddressGetIface(namespace, name string) (
function AddressGetIfaceMod (line 126) | func AddressGetIfaceMod(namespace, name string) (
FILE: iproute/bridge.go
function BridgeAdd (line 7) | func BridgeAdd(namespace, name string) (err error) {
function BridgeDelete (line 39) | func BridgeDelete(namespace, name string) (err error) {
FILE: iproute/iface.go
type Iface (line 11) | type Iface struct
function IfaceGetAll (line 16) | func IfaceGetAll(namespace string) (ifaces []*Iface, err error) {
function IfaceGetBridges (line 49) | func IfaceGetBridges(namespace string) (ifaces []*Iface, err error) {
function IfaceGetBridgeIfaces (line 84) | func IfaceGetBridgeIfaces(namespace, bridge string) (
FILE: ipset/names.go
type Names (line 8) | type Names struct
method Apply (line 13) | func (n *Names) Apply(curNames *Names) (err error) {
FILE: ipset/sets.go
type Sets (line 10) | type Sets struct
method Apply (line 15) | func (s *Sets) Apply(curSets *Sets) (err error) {
FILE: ipset/state.go
type State (line 10) | type State struct
method AddIngress (line 14) | func (s *State) AddIngress(namespace string, ingress []*firewall.Rule) {
method AddSourceDestCheck (line 60) | func (s *State) AddSourceDestCheck(namespace, addr6 string) {
method AddMember (line 78) | func (s *State) AddMember(namespace string, ruleName, member string) {
type NamesState (line 101) | type NamesState struct
method AddIngress (line 105) | func (n *NamesState) AddIngress(namespace string, ingress []*firewall....
method AddSourceDestCheck (line 141) | func (n *NamesState) AddSourceDestCheck(namespace string) {
method AddName (line 154) | func (n *NamesState) AddName(namespace string, ruleName string) {
FILE: ipset/utils.go
function UpdateState (line 21) | func UpdateState(instances []*instance.Instance, namespaces []string,
function applyState (line 75) | func applyState(oldState, newState *State, namespaces []string) (err err...
function UpdateNamesState (line 106) | func UpdateNamesState(instances []*instance.Instance,
function applyNamesState (line 155) | func applyNamesState(oldNamesState, newNamesState *NamesState) (err erro...
function loadIpset (line 168) | func loadIpset(namespace string, state *State, namesState *NamesState) (
function Init (line 207) | func Init(namespaces []string, instances []*instance.Instance,
function InitNames (line 241) | func InitNames(namespaces []string, instances []*instance.Instance,
FILE: iptables/iptables.go
method newCommand (line 24) | func (r *Rules) newCommand() (cmd []string) {
method newCommandNatPre (line 39) | func (r *Rules) newCommandNatPre() (cmd []string) {
method newCommandNatPost (line 47) | func (r *Rules) newCommandNatPost() (cmd []string) {
method newCommandMap (line 55) | func (r *Rules) newCommandMap() (cmd []string) {
method newCommandMapPost (line 63) | func (r *Rules) newCommandMapPost() (cmd []string) {
method commentCommand (line 71) | func (r *Rules) commentCommand(inCmd []string, hold bool) (cmd []string) {
method commentCommandHeader (line 87) | func (r *Rules) commentCommandHeader(inCmd []string) (cmd []string) {
method commentCommandSdc (line 96) | func (r *Rules) commentCommandSdc(inCmd []string) (cmd []string) {
method commentCommandNat (line 105) | func (r *Rules) commentCommandNat(inCmd []string) (cmd []string) {
method commentCommandMap (line 114) | func (r *Rules) commentCommandMap(inCmd []string) (cmd []string) {
method run (line 123) | func (r *Rules) run(table string, cmds [][]string,
method Apply (line 189) | func (r *Rules) Apply(diff *RulesDiff) (err error) {
method Hold (line 279) | func (r *Rules) Hold() (err error) {
method Remove (line 377) | func (r *Rules) Remove(diff *RulesDiff) (err error) {
function generateVirt (line 473) | func generateVirt(vc *vpc.Vpc, namespace, iface, addr, addr6 string,
function generateInternal (line 966) | func generateInternal(namespace, iface string, nat, nat6, dhcp, dhcp6 bool,
function generateNodePort (line 1390) | func generateNodePort(namespace, iface string, addr, nodePortGateway str...
function generateHost (line 1507) | func generateHost(namespace, iface string, nodePortNetwork bool,
function generateHostNodePort (line 1967) | func generateHostNodePort(namespace, iface string,
FILE: iptables/lock.go
function Lock (line 9) | func Lock() {
function Unlock (line 13) | func Unlock() {
FILE: iptables/rules.go
type Rules (line 7) | type Rules struct
type RulesDiff (line 25) | type RulesDiff struct
FILE: iptables/state.go
type State (line 14) | type State struct
function LoadState (line 18) | func LoadState(nodeSelf *node.Node, vpcs []*vpc.Vpc,
FILE: iptables/update.go
type Update (line 18) | type Update struct
method Apply (line 25) | func (u *Update) Apply() {
method Recover (line 167) | func (u *Update) Recover() {
method reload (line 193) | func (u *Update) reload() (err error) {
function ApplyUpdate (line 243) | func ApplyUpdate(newState *State, namespaces []string, recover bool) {
function UpdateState (line 266) | func UpdateState(nodeSelf *node.Node, vpcs []*vpc.Vpc,
function UpdateStateRecover (line 279) | func UpdateStateRecover(nodeSelf *node.Node, vpcs []*vpc.Vpc,
FILE: iptables/utils.go
function diffCmd (line 18) | func diffCmd(a, b []string) bool {
function diffRules (line 32) | func diffRules(a, b *Rules) *RulesDiff {
function getIptablesCmd (line 199) | func getIptablesCmd(ipv6 bool) string {
function loadIptables (line 207) | func loadIptables(namespace, instIface string, state *State,
function RecoverNode (line 664) | func RecoverNode() (err error) {
function Init (line 726) | func Init(namespaces []string, vpcs []*vpc.Vpc,
function protocolIndex (line 829) | func protocolIndex(proto string) string {
FILE: ipvs/constants.go
constant Tcp (line 4) | Tcp = "-t"
constant Udp (line 5) | Udp = "-u"
constant RoundRobin (line 7) | RoundRobin = "rr"
FILE: ipvs/ipvs.go
type State (line 18) | type State struct
method Print (line 22) | func (s *State) Print() string {
method AddTarget (line 72) | func (s *State) AddTarget(serviceAddr, targetAddr string,
function UpdateState (line 99) | func UpdateState(newState *State) (err error) {
function LoadState (line 261) | func LoadState() (state *State, err error) {
function New (line 383) | func New() *State {
FILE: ipvs/service.go
type Service (line 15) | type Service struct
method Key (line 23) | func (s *Service) Key() string {
method Add (line 27) | func (s *Service) Add() (err error) {
method Delete (line 69) | func (s *Service) Delete() (err error) {
FILE: ipvs/target.go
type Target (line 11) | type Target struct
method Key (line 19) | func (t *Target) Key() string {
method Add (line 23) | func (t *Target) Add() (err error) {
method Delete (line 55) | func (t *Target) Delete() (err error) {
FILE: iscsi/iscsi.go
type Device (line 12) | type Device struct
method Json (line 22) | func (d *Device) Json() {
method QemuUri (line 43) | func (d *Device) QemuUri() (uriStr string) {
method Parse (line 72) | func (d *Device) Parse() (errData *errortypes.ErrorData, err error) {
FILE: iso/iso.go
type Iso (line 20) | type Iso struct
function GetIsos (line 24) | func GetIsos(isoDir string) (isos []*Iso, err error) {
FILE: journal/constants.go
constant InstanceAgent (line 4) | InstanceAgent = 1
constant DeploymentAgent (line 5) | DeploymentAgent = 2
constant Panic (line 9) | Panic = 1
constant Critical (line 10) | Critical = 2
constant Error (line 11) | Error = 3
constant Warning (line 12) | Warning = 4
constant Info (line 13) | Info = 5
constant Debug (line 14) | Debug = 6
constant Trace (line 15) | Trace = 7
FILE: journal/journal.go
type Journal (line 11) | type Journal struct
method String (line 22) | func (j *Journal) String() string {
method Insert (line 30) | func (j *Journal) Insert(db *database.Database) (err error) {
FILE: journal/store.go
type KindGenerator (line 7) | type KindGenerator interface
FILE: journal/utils.go
function GetOutput (line 13) | func GetOutput(c context.Context, db *database.Database,
function Remove (line 68) | func Remove(db *database.Database, resource bson.ObjectID,
function RemoveAll (line 90) | func RemoveAll(db *database.Database, resource bson.ObjectID) (err error) {
FILE: lock/lvm.go
type LvmLocker (line 12) | type LvmLocker struct
function LvmLock (line 18) | func LvmLock(db *database.Database, vgName, lvName string) (
function LvmRelock (line 44) | func LvmRelock(db *database.Database, vgName, lvName string) (err error) {
function LvmUnlock (line 61) | func LvmUnlock(db *database.Database, vgName, lvName string) (err error) {
FILE: log/constants.go
constant Debug (line 4) | Debug = "debug"
constant Info (line 5) | Info = "info"
constant Warning (line 6) | Warning = "warning"
constant Error (line 7) | Error = "error"
constant Fatal (line 8) | Fatal = "fatal"
constant Panic (line 9) | Panic = "panic"
constant Unknown (line 10) | Unknown = "unknown"
FILE: log/log.go
type Entry (line 16) | type Entry struct
method Insert (line 25) | func (e *Entry) Insert(db *database.Database) (err error) {
function publish (line 46) | func publish() {
function initSender (line 53) | func initSender() {
function init (line 63) | func init() {
FILE: log/utils.go
function Get (line 11) | func Get(db *database.Database, logId bson.ObjectID) (
function GetAll (line 25) | func GetAll(db *database.Database, query *bson.M, page, pageCount int64) (
function Clear (line 89) | func Clear(db *database.Database) (err error) {
FILE: logger/database.go
type databaseSender (line 17) | type databaseSender struct
method Init (line 19) | func (s *databaseSender) Init() {}
method Parse (line 21) | func (s *databaseSender) Parse(entry *logrus.Entry) {
function databaseSend (line 27) | func databaseSend(entry *logrus.Entry) (err error) {
function initDatabaseSender (line 82) | func initDatabaseSender() {
function init (line 105) | func init() {
FILE: logger/file.go
type fileSender (line 12) | type fileSender struct
method Init (line 14) | func (s *fileSender) Init() {}
method Parse (line 16) | func (s *fileSender) Parse(entry *logrus.Entry) {
method send (line 25) | func (s *fileSender) send(entry *logrus.Entry) (err error) {
function init (line 78) | func init() {
FILE: logger/formatter.go
function format (line 19) | func format(entry *logrus.Entry) (output []byte) {
function formatPlain (line 69) | func formatPlain(entry *logrus.Entry) (output []byte) {
function formatTime (line 117) | func formatTime(timestamp time.Time) (str string) {
function formatLevel (line 125) | func formatLevel(lvl logrus.Level) (str string) {
function formatLevelPlain (line 153) | func formatLevelPlain(lvl logrus.Level) string {
type formatter (line 171) | type formatter struct
method Format (line 173) | func (f *formatter) Format(entry *logrus.Entry) ([]byte, error) {
FILE: logger/hook.go
type logHook (line 9) | type logHook struct
method Fire (line 11) | func (h *logHook) Fire(entry *logrus.Entry) (err error) {
method Levels (line 23) | func (h *logHook) Levels() []logrus.Level {
FILE: logger/limiter.go
type limiter (line 10) | type limiter
method Check (line 12) | func (l limiter) Check(entry *logrus.Entry, limit time.Duration) bool {
FILE: logger/logger.go
function initSender (line 17) | func initSender() {
function Init (line 41) | func Init() {
function InitStdout (line 48) | func InitStdout() {
function init (line 54) | func init() {
FILE: logger/sender.go
type sender (line 7) | type sender interface
FILE: logger/writer.go
type ErrorWriter (line 9) | type ErrorWriter struct
method Write (line 15) | func (w *ErrorWriter) Write(input []byte) (n int, err error) {
FILE: lvm/lv.go
function CreateLv (line 15) | func CreateLv(vgName, lvName string, size int) (err error) {
function RemoveLv (line 26) | func RemoveLv(vgName, lvName string) (err error) {
function ActivateLv (line 37) | func ActivateLv(vgName, lvName string) (err error) {
function DeactivateLv (line 47) | func DeactivateLv(vgName, lvName string) (err error) {
function WriteLv (line 57) | func WriteLv(vgName, lvName, sourcePth string) (err error) {
function ExtendLv (line 71) | func ExtendLv(vgName, lvName string, addSize int) (err error) {
function GetSizeLv (line 82) | func GetSizeLv(vgName, lvName string) (size int, err error) {
function HasLocking (line 105) | func HasLocking(vgName string) (hasLock bool, err error) {
function IsLockspaceActive (line 118) | func IsLockspaceActive(vgName string) (isLocked bool, err error) {
function InitLock (line 138) | func InitLock(vgName string) (err error) {
FILE: lvm/vgs.go
type report (line 21) | type report struct
type vgReport (line 25) | type vgReport struct
type vgDetails (line 29) | type vgDetails struct
function GetAvailablePools (line 39) | func GetAvailablePools(db *database.Database, zoneId bson.ObjectID) (
FILE: main.go
constant help (line 16) | help = `
function Init (line 38) | func Init() {
function InitLimited (line 43) | func InitLimited() {
function main (line 48) | func main() {
FILE: middlewear/gzip.go
type GzipWriter (line 11) | type GzipWriter struct
method Header (line 16) | func (g *GzipWriter) Header() http.Header {
method WriteHeader (line 20) | func (g *GzipWriter) WriteHeader(statusCode int) {
method Write (line 24) | func (g *GzipWriter) Write(b []byte) (int, error) {
method Close (line 31) | func (g *GzipWriter) Close() {
function NewGzipWriter (line 37) | func NewGzipWriter(c *gin.Context) *GzipWriter {
FILE: middlewear/middlewear.go
constant robots (line 24) | robots = `User-agent: *
function Limiter (line 28) | func Limiter(c *gin.Context) {
function Counter (line 32) | func Counter(c *gin.Context) {
function Database (line 36) | func Database(c *gin.Context) {
function Headers (line 43) | func Headers(c *gin.Context) {
function SessionAdmin (line 53) | func SessionAdmin(c *gin.Context) {
function SessionUser (line 101) | func SessionUser(c *gin.Context) {
function AuthAdmin (line 148) | func AuthAdmin(c *gin.Context) {
function AuthUser (line 207) | func AuthUser(c *gin.Context) {
function UserOrg (line 266) | func UserOrg(c *gin.Context) {
function CsrfToken (line 313) | func CsrfToken(c *gin.Context) {
function Recovery (line 351) | func Recovery(c *gin.Context) {
function RobotsGet (line 374) | func RobotsGet(c *gin.Context) {
function NotFound (line 378) | func NotFound(c *gin.Context) {
FILE: mtu/mtu.go
type Check (line 21) | type Check struct
method host (line 30) | func (c *Check) host(db *database.Database) (err error) {
method instances (line 99) | func (c *Check) instances(db *database.Database) (err error) {
method Run (line 161) | func (c *Check) Run() (err error) {
function NewCheck (line 199) | func NewCheck() (chk *Check) {
FILE: netconf/address.go
method Address (line 15) | func (n *NetConf) Address(db *database.Database) (err error) {
FILE: netconf/base.go
method Base (line 8) | func (n *NetConf) Base(db *database.Database) (err error) {
FILE: netconf/bridge.go
method bridgeNet (line 10) | func (n *NetConf) bridgeNet(db *database.Database) (err error) {
method bridgeMaster (line 49) | func (n *NetConf) bridgeMaster(db *database.Database) (err error) {
method bridgeRoute (line 73) | func (n *NetConf) bridgeRoute(db *database.Database) (err error) {
method bridgeIptables (line 99) | func (n *NetConf) bridgeIptables(db *database.Database) (err error) {
method bridgeUp (line 199) | func (n *NetConf) bridgeUp(db *database.Database) (err error) {
method Bridge (line 223) | func (n *NetConf) Bridge(db *database.Database) (err error) {
FILE: netconf/clear.go
method Clear (line 14) | func (n *NetConf) Clear(db *database.Database) (err error) {
method ClearAll (line 39) | func (n *NetConf) ClearAll(db *database.Database) (err error) {
function clearIface (line 59) | func clearIface(namespace, iface string) {
FILE: netconf/external.go
method externalNet (line 15) | func (n *NetConf) externalNet(db *database.Database) (err error) {
method externalMtu (line 59) | func (n *NetConf) externalMtu(db *database.Database) (err error) {
method externalUp (line 98) | func (n *NetConf) externalUp(db *database.Database) (err error) {
method externalSysctl (line 118) | func (n *NetConf) externalSysctl(db *database.Database) (err error) {
method externalMaster (line 144) | func (n *NetConf) externalMaster(db *database.Database) (err error) {
method externalSpace (line 165) | func (n *NetConf) externalSpace(db *database.Database) (err error) {
method externalSpaceMod (line 195) | func (n *NetConf) externalSpaceMod(db *database.Database) (err error) {
method externalSpaceSysctl (line 253) | func (n *NetConf) externalSpaceSysctl(db *database.Database) (err error) {
method externalSpaceUp (line 357) | func (n *NetConf) externalSpaceUp(db *database.Database) (err error) {
method External (line 401) | func (n *NetConf) External(db *database.Database) (err error) {
FILE: netconf/host.go
method hostNet (line 11) | func (n *NetConf) hostNet(db *database.Database) (err error) {
method hostMtu (line 38) | func (n *NetConf) hostMtu(db *database.Database) (err error) {
method hostUp (line 65) | func (n *NetConf) hostUp(db *database.Database) (err error) {
method hostMaster (line 80) | func (n *NetConf) hostMaster(db *database.Database) (err error) {
method hostSpace (line 96) | func (n *NetConf) hostSpace(db *database.Database) (err error) {
method hostSpaceUp (line 122) | func (n *NetConf) hostSpaceUp(db *database.Database) (err error) {
method Host (line 138) | func (n *NetConf) Host(db *database.Database) (err error) {
FILE: netconf/iface.go
method Iface1 (line 18) | func (n *NetConf) Iface1(db *database.Database) (err error) {
method Iface2 (line 105) | func (n *NetConf) Iface2(db *database.Database, clean bool) (err error) {
FILE: netconf/imds.go
method imdsNet (line 10) | func (n *NetConf) imdsNet(db *database.Database) (err error) {
method imdsMtu (line 28) | func (n *NetConf) imdsMtu(db *database.Database) (err error) {
method imdsAddr (line 43) | func (n *NetConf) imdsAddr(db *database.Database) (err error) {
method imdsUp (line 58) | func (n *NetConf) imdsUp(db *database.Database) (err error) {
method imdsStart (line 72) | func (n *NetConf) imdsStart(db *database.Database) (err error) {
method Imds (line 81) | func (n *NetConf) Imds(db *database.Database) (err error) {
FILE: netconf/internal.go
method internalNet (line 11) | func (n *NetConf) internalNet(db *database.Database) (err error) {
method internalMtu (line 51) | func (n *NetConf) internalMtu(db *database.Database) (err error) {
method internalUp (line 78) | func (n *NetConf) internalUp(db *database.Database) (err error) {
method internalMaster (line 93) | func (n *NetConf) internalMaster(db *database.Database) (err error) {
method internalSpace (line 109) | func (n *NetConf) internalSpace(db *database.Database) (err error) {
method internalSpaceUp (line 135) | func (n *NetConf) internalSpaceUp(db *database.Database) (err error) {
method Internal (line 149) | func (n *NetConf) Internal(db *database.Database) (err error) {
FILE: netconf/ip.go
method ipExternal (line 23) | func (n *NetConf) ipExternal(db *database.Database) (err error) {
method ipHost (line 250) | func (n *NetConf) ipHost(db *database.Database) (err error) {
method ipNodePort (line 280) | func (n *NetConf) ipNodePort(db *database.Database) (err error) {
method ipDetect (line 297) | func (n *NetConf) ipDetect(db *database.Database) (err error) {
method ipHostIptables (line 378) | func (n *NetConf) ipHostIptables(db *database.Database) (err error) {
method ipDatabase (line 456) | func (n *NetConf) ipDatabase(db *database.Database) (err error) {
method ipInit6 (line 525) | func (n *NetConf) ipInit6(db *database.Database) (err error) {
method ipArp (line 592) | func (n *NetConf) ipArp(db *database.Database) (err error) {
method ipInit6Alt (line 660) | func (n *NetConf) ipInit6Alt(db *database.Database) (err error) {
method Ip (line 702) | func (n *NetConf) Ip(db *database.Database) (err error) {
FILE: netconf/netconf.go
type NetConf (line 17) | type NetConf struct
method Init (line 112) | func (n *NetConf) Init(db *database.Database) (err error) {
method Clean (line 196) | func (n *NetConf) Clean(db *database.Database) (err error) {
FILE: netconf/nodeport.go
method nodePortNet (line 11) | func (n *NetConf) nodePortNet(db *database.Database) (err error) {
method nodePortMtu (line 38) | func (n *NetConf) nodePortMtu(db *database.Database) (err error) {
method nodePortUp (line 65) | func (n *NetConf) nodePortUp(db *database.Database) (err error) {
method nodePortMaster (line 80) | func (n *NetConf) nodePortMaster(db *database.Database) (err error) {
method nodePortSpace (line 96) | func (n *NetConf) nodePortSpace(db *database.Database) (err error) {
method nodePortSpaceUp (line 122) | func (n *NetConf) nodePortSpaceUp(db *database.Database) (err error) {
method NodePort (line 138) | func (n *NetConf) NodePort(db *database.Database) (err error) {
FILE: netconf/oracle.go
method oracleInitVnic (line 19) | func (n *NetConf) oracleInitVnic(db *database.Database) (err error) {
method oracleConfVnic (line 92) | func (n *NetConf) oracleConfVnic(db *database.Database) (err error) {
method oracleConfVnicMetal (line 116) | func (n *NetConf) oracleConfVnicMetal(db *database.Database) (err error) {
method oracleConfVnicVirt (line 266) | func (n *NetConf) oracleConfVnicVirt(db *database.Database) (err error) {
method oracleMtu (line 386) | func (n *NetConf) oracleMtu(db *database.Database) (err error) {
method oracleIp (line 414) | func (n *NetConf) oracleIp(db *database.Database) (err error) {
method oracleUp (line 460) | func (n *NetConf) oracleUp(db *database.Database) (err error) {
method oracleRoute (line 486) | func (n *NetConf) oracleRoute(db *database.Database) (err error) {
method Oracle (line 516) | func (n *NetConf) Oracle(db *database.Database) (err error) {
FILE: netconf/space.go
method spaceSysctl (line 12) | func (n *NetConf) spaceSysctl(db *database.Database) (err error) {
method spaceForward (line 77) | func (n *NetConf) spaceForward(db *database.Database) (err error) {
method spaceVirt (line 207) | func (n *NetConf) spaceVirt(db *database.Database) (err error) {
method spaceLoopback (line 224) | func (n *NetConf) spaceLoopback(db *database.Database) (err error) {
method spaceMtu (line 238) | func (n *NetConf) spaceMtu(db *database.Database) (err error) {
method spaceUp (line 255) | func (n *NetConf) spaceUp(db *database.Database) (err error) {
method Space (line 269) | func (n *NetConf) Space(db *database.Database) (err error) {
FILE: netconf/utils.go
function New (line 10) | func New(virt *vm.VirtualMachine) *NetConf {
function Destroy (line 16) | func Destroy(db *database.Database, virt *vm.VirtualMachine) (err error) {
FILE: netconf/validate.go
method Validate (line 14) | func (n *NetConf) Validate() (err error) {
FILE: netconf/vlan.go
method vlanNet (line 10) | func (n *NetConf) vlanNet(db *database.Database) (err error) {
method vlanMtu (line 27) | func (n *NetConf) vlanMtu(db *database.Database) (err error) {
method vlanUp (line 44) | func (n *NetConf) vlanUp(db *database.Database) (err error) {
method Vlan (line 58) | func (n *NetConf) Vlan(db *database.Database) (err error) {
FILE: node/block.go
type BlockAttachment (line 5) | type BlockAttachment struct
FILE: node/certificate.go
function selfCert (line 20) | func selfCert(parent *x509.Certificate, parentKey *ecdsa.PrivateKey) (
function SelfCert (line 86) | func SelfCert() (certPem, keyPem []byte, err error) {
FILE: node/constants.go
constant Admin (line 8) | Admin = "admin"
constant User (line 9) | User = "user"
constant Balancer (line 10) | Balancer = "balancer"
constant Hypervisor (line 11) | Hypervisor = "hypervisor"
constant Qemu (line 13) | Qemu = "qemu"
constant Kvm (line 14) | Kvm = "kvm"
constant Std (line 17) | Std = "std"
constant Vmware (line 19) | Vmware = "vmware"
constant Virtio (line 21) | Virtio = "virtio"
constant VirtioPci (line 23) | VirtioPci = "virtio_pci"
constant VirtioVgaGl (line 25) | VirtioVgaGl = "virtio_vga_gl"
constant VirtioVgaGlVulkan (line 27) | VirtioVgaGlVulkan = "virtio_vga_gl_vulkan"
constant VirtioGl (line 29) | VirtioGl = "virtio_gl"
constant VirtioGlVulkan (line 31) | VirtioGlVulkan = "virtio_gl_vulkan"
constant VirtioPciGl (line 33) | VirtioPciGl = "virtio_pci_gl"
constant VirtioPciGlVulkan (line 35) | VirtioPciGlVulkan = "virtio_pci_gl_vulkan"
constant VirtioPrime (line 37) | VirtioPrime = "virtio_prime"
constant VirtioPciPrime (line 39) | VirtioPciPrime = "virtio_pci_prime"
constant VirtioVgaGlPrime (line 41) | VirtioVgaGlPrime = "virtio_vga_gl_prime"
constant VirtioVgaGlVulkanPrime (line 43) | VirtioVgaGlVulkanPrime = "virtio_vga_gl_vulkan_prime"
constant VirtioGlPrime (line 45) | VirtioGlPrime = "virtio_gl_prime"
constant VirtioGlVulkanPrime (line 47) | VirtioGlVulkanPrime = "virtio_gl_vulkan_prime"
constant VirtioPciGlPrime (line 49) | VirtioPciGlPrime = "virtio_pci_gl_prime"
constant VirtioPciGlVulkanPrime (line 51) | VirtioPciGlVulkanPrime = "virtio_pci_gl_vulkan_prime"
constant Sdl (line 53) | Sdl = "sdl"
constant Gtk (line 54) | Gtk = "gtk"
constant Disabled (line 56) | Disabled = "disabled"
constant Dhcp (line 57) | Dhcp = "dhcp"
constant DhcpSlaac (line 58) | DhcpSlaac = "dhcp_slaac"
constant Slaac (line 59) | Slaac = "slaac"
constant Static (line 60) | Static = "static"
constant Internal (line 61) | Internal = "internal"
constant Cloud (line 62) | Cloud = "cloud"
constant Restart (line 64) | Restart = "restart"
constant HostPath (line 66) | HostPath = "host_path"
FILE: node/interfaces.go
function ClearIfaceCache (line 21) | func ClearIfaceCache() {
function GetInterfaces (line 28) | func GetInterfaces() (ifaces []ip.Interface, err error) {
function getDefaultIface (line 75) | func getDefaultIface() (iface string, err error) {
FILE: node/node.go
type Node (line 49) | type Node struct
method Copy (line 192) | func (n *Node) Copy() *Node {
method AddRequest (line 289) | func (n *Node) AddRequest() {
method GetVirtPath (line 296) | func (n *Node) GetVirtPath() string {
method GetCachePath (line 303) | func (n *Node) GetCachePath() string {
method GetTempPath (line 310) | func (n *Node) GetTempPath() string {
method GetDatacenter (line 317) | func (n *Node) GetDatacenter(db *database.Database) (
method GetCloudSubnetsName (line 342) | func (n *Node) GetCloudSubnetsName() (subnets []*CloudSubnet) {
method IsAdmin (line 384) | func (n *Node) IsAdmin() bool {
method IsUser (line 393) | func (n *Node) IsUser() bool {
method IsBalancer (line 402) | func (n *Node) IsBalancer() bool {
method IsHypervisor (line 411) | func (n *Node) IsHypervisor() bool {
method IsOnline (line 420) | func (n *Node) IsOnline() bool {
method IsDhcp (line 429) | func (n *Node) IsDhcp() bool {
method IsDhcp6 (line 434) | func (n *Node) IsDhcp6() bool {
method Usage (line 439) | func (n *Node) Usage() int {
method SizeResource (line 458) | func (n *Node) SizeResource(memory, processors int) bool {
method GetOracleAuthProvider (line 472) | func (n *Node) GetOracleAuthProvider() (pv *NodeOracleAuthProvider) {
method GetWebauthn (line 479) | func (n *Node) GetWebauthn(origin string, strict bool) (
method Validate (line 514) | func (n *Node) Validate(db *database.Database) (
method Format (line 853) | func (n *Node) Format() {
method JsonHypervisor (line 858) | func (n *Node) JsonHypervisor() {
method SetActive (line 884) | func (n *Node) SetActive() {
method Commit (line 898) | func (n *Node) Commit(db *database.Database) (err error) {
method CommitFields (line 909) | func (n *Node) CommitFields(db *database.Database, fields set.Set) (
method GetStaticAddr (line 922) | func (n *Node) GetStaticAddr(db *database.Database,
method GetStaticAddr6 (line 977) | func (n *Node) GetStaticAddr6(db *database.Database,
method GetStaticHostAddr (line 1049) | func (n *Node) GetStaticHostAddr(db *database.Database,
method GetStaticNodePortAddr (line 1099) | func (n *Node) GetStaticNodePortAddr(db *database.Database,
method GetRemoteAddr (line 1149) | func (n *Node) GetRemoteAddr(r *http.Request) (addr string) {
method SyncNetwork (line 1162) | func (n *Node) SyncNetwork(clearCache bool) {
method getUpdateDetails (line 1268) | func (n *Node) getUpdateDetails(db *database.Database) (
method update (line 1296) | func (n *Node) update(db *database.Database) (err error) {
method sync (line 1409) | func (n *Node) sync() (nde *Node) {
method Init (line 1590) | func (n *Node) Init() (err error) {
type Completion (line 141) | type Completion struct
method IsHypervisor (line 148) | func (n *Completion) IsHypervisor() bool {
type Share (line 157) | type Share struct
method MatchPath (line 163) | func (s *Share) MatchPath(pth string) bool {
type CloudSubnet (line 187) | type CloudSubnet struct
FILE: node/oracle.go
type NodeOracleAuthProvider (line 3) | type NodeOracleAuthProvider struct
method OracleUser (line 7) | func (n *NodeOracleAuthProvider) OracleUser() string {
method OracleTenancy (line 11) | func (n *NodeOracleAuthProvider) OracleTenancy() string {
method OraclePrivateKey (line 15) | func (n *NodeOracleAuthProvider) OraclePrivateKey() string {
FILE: node/utils.go
function Get (line 10) | func Get(db *database.Database, nodeId bson.ObjectID) (
function GetAll (line 24) | func GetAll(db *database.Database) (nodes []*Node, err error) {
function GetOne (line 56) | func GetOne(db *database.Database, query *bson.M) (nde *Node, err error) {
function GetAllNamesMap (line 69) | func GetAllNamesMap(db *database.Database, query *bson.M) (
function GetAllHypervisors (line 108) | func GetAllHypervisors(db *database.Database, query *bson.M) (
function GetAllPool (line 163) | func GetAllPool(db *database.Database, poolId bson.ObjectID) (
function GetAllPaged (line 204) | func GetAllPaged(db *database.Database, query *bson.M,
function GetAllShape (line 271) | func GetAllShape(db *database.Database, zones []bson.ObjectID,
function GetAllNet (line 321) | func GetAllNet(db *database.Database) (nodes []*Node, err error) {
function Remove (line 356) | func Remove(db *database.Database, nodeId bson.ObjectID) (err error) {
FILE: nodeport/constants.go
constant Tcp (line 4) | Tcp = "tcp"
constant Udp (line 5) | Udp = "udp"
FILE: nodeport/mapping.go
type Mapping (line 9) | type Mapping struct
method Validate (line 17) | func (m *Mapping) Validate(db *database.Database) (
method Diff (line 66) | func (m *Mapping) Diff(mapping *Mapping) bool {
FILE: nodeport/network.go
function init (line 16) | func init() {
FILE: nodeport/nodeport.go
type NodePort (line 10) | type NodePort struct
method Validate (line 18) | func (n *NodePort) Validate(db *database.Database) (
method Sync (line 59) | func (n *NodePort) Sync(db *database.Database) (err error) {
method CommitFields (line 80) | func (n *NodePort) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 93) | func (n *NodePort) Insert(db *database.Database) (err error) {
FILE: nodeport/utils.go
type PortRange (line 16) | type PortRange struct
method Contains (line 21) | func (r *PortRange) Contains(port int) bool {
function Get (line 28) | func Get(db *database.Database, ndePrtId bson.ObjectID) (
function GetOrg (line 45) | func GetOrg(db *database.Database, orgId, ndePrtId bson.ObjectID) (
function GetPort (line 63) | func GetPort(db *database.Database, dcId, orgId bson.ObjectID,
function Available (line 81) | func Available(db *database.Database, datacenterId, orgId bson.ObjectID,
function GetPortRanges (line 102) | func GetPortRanges() (ranges []*PortRange, err error) {
function New (line 159) | func New(db *database.Database, dcId, orgId bson.ObjectID,
function Remove (line 226) | func Remove(db *database.Database, ndePrtId bson.ObjectID) (
FILE: nonce/nonce.go
type nonce (line 11) | type nonce struct
function Validate (line 16) | func Validate(db *database.Database, nce string) (err error) {
FILE: notification/notification.go
type notificationResp (line 34) | type notificationResp struct
function Check (line 39) | func Check() (err error) {
FILE: oracle/iface.go
type Iface (line 11) | type Iface struct
function GetIfaces (line 23) | func GetIfaces(logOutput bool) (ifaces []*Iface, err error) {
function ConfIfaces (line 80) | func ConfIfaces(logOutput bool) (err error) {
FILE: oracle/metadata.go
type Metadata (line 17) | type Metadata struct
type OciMetaVnic (line 27) | type OciMetaVnic struct
type OciMetaInstance (line 40) | type OciMetaInstance struct
type OciMeta (line 48) | type OciMeta struct
method IsBareMetal (line 53) | func (o *OciMeta) IsBareMetal() bool {
function GetMetadata (line 60) | func GetMetadata(authPv AuthProvider) (mdata *Metadata, err error) {
function GetOciMetadata (line 108) | func GetOciMetadata() (mdata *OciMeta, err error) {
FILE: oracle/oracle.go
type AuthProvider (line 3) | type AuthProvider interface
FILE: oracle/provider.go
type Provider (line 14) | type Provider struct
method LogInfo (line 26) | func (p *Provider) LogInfo() {
method AuthType (line 38) | func (p *Provider) AuthType() (common.AuthConfig, error) {
method PrivateRSAKey (line 46) | func (p *Provider) PrivateRSAKey() (*rsa.PrivateKey, error) {
method KeyID (line 50) | func (p *Provider) KeyID() (string, error) {
method TenancyOCID (line 54) | func (p *Provider) TenancyOCID() (string, error) {
method UserOCID (line 58) | func (p *Provider) UserOCID() (string, error) {
method KeyFingerprint (line 62) | func (p *Provider) KeyFingerprint() (string, error) {
method Region (line 66) | func (p *Provider) Region() (string, error) {
method CompartmentOCID (line 70) | func (p *Provider) CompartmentOCID() (string, error) {
method GetNetworkClient (line 74) | func (p *Provider) GetNetworkClient() (
method GetComputeClient (line 96) | func (p *Provider) GetComputeClient() (
function NewProvider (line 118) | func NewProvider(authPv AuthProvider) (prov *Provider, err error) {
FILE: oracle/routetable.go
type RouteTable (line 11) | type RouteTable struct
method RouteExists (line 18) | func (r *RouteTable) RouteExists(dest string, nextHopId string) bool {
method RouteUpsert (line 25) | func (r *RouteTable) RouteUpsert(dest string, nextHopId string) bool {
method CommitRouteRules (line 50) | func (r *RouteTable) CommitRouteRules(pv *Provider) (err error) {
function GetRouteTables (line 74) | func GetRouteTables(pv *Provider, vcnId string) (
FILE: oracle/subnet.go
type Vcn (line 12) | type Vcn struct
type Subnet (line 19) | type Subnet struct
function GetSubnet (line 26) | func GetSubnet(pv *Provider, subnetId string) (subnet *Subnet, err error) {
function GetVcns (line 61) | func GetVcns(pv *Provider) (vcns []*Vcn, err error) {
function GetSubnets (line 114) | func GetSubnets(pv *Provider, vcnId string) (subnets []*Subnet, err erro...
FILE: oracle/utils.go
function loadPrivateKey (line 15) | func loadPrivateKey(mdata *Metadata) (
FILE: oracle/vnic.go
type Vnic (line 14) | type Vnic struct
method SetSkipSourceDestCheck (line 26) | func (v *Vnic) SetSkipSourceDestCheck(pv *Provider, val bool) (err err...
function GetVnic (line 50) | func GetVnic(pv *Provider, vnicId string) (vnic *Vnic, err error) {
function getVnicAttachment (line 131) | func getVnicAttachment(pv *Provider, attachmentId string) (
function CreateVnic (line 158) | func CreateVnic(pv *Provider, name, subnetId string,
function RemoveVnic (line 243) | func RemoveVnic(pv *Provider, vnicAttachId string) (err error) {
FILE: organization/organization.go
type Organization (line 12) | type Organization struct
method Validate (line 19) | func (d *Organization) Validate(db *database.Database) (
method Commit (line 31) | func (d *Organization) Commit(db *database.Database) (err error) {
method CommitFields (line 42) | func (d *Organization) CommitFields(db *database.Database, fields set....
method Insert (line 55) | func (c *Organization) Insert(db *database.Database) (err error) {
FILE: organization/utils.go
function Get (line 10) | func Get(db *database.Database, dcId bson.ObjectID) (
function GetAll (line 24) | func GetAll(db *database.Database, query *bson.M) (
function GetAllName (line 62) | func GetAllName(db *database.Database) (orgs []*Organization, err error) {
function GetAllNameRoles (line 99) | func GetAllNameRoles(db *database.Database, roles []string) (
function GetAllPaged (line 141) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 205) | func Remove(db *database.Database, dcId bson.ObjectID) (err error) {
function Count (line 224) | func Count(db *database.Database) (count int64, err error) {
FILE: paths/paths.go
function GetVmUuid (line 16) | func GetVmUuid(instId bson.ObjectID) string {
function GetVmPath (line 37) | func GetVmPath(instId bson.ObjectID) string {
function GetDisksPath (line 42) | func GetDisksPath() string {
function GetLocalIsosPath (line 46) | func GetLocalIsosPath() string {
function GetBackingPath (line 50) | func GetBackingPath() string {
function GetTpmsPath (line 54) | func GetTpmsPath() string {
function GetTpmPath (line 58) | func GetTpmPath(virtId bson.ObjectID) string {
function GetTpmSockPath (line 62) | func GetTpmSockPath(virtId bson.ObjectID) string {
function GetTpmPwdPath (line 66) | func GetTpmPwdPath(virtId bson.ObjectID) string {
function GetTempPath (line 70) | func GetTempPath() string {
function GetTempDir (line 74) | func GetTempDir() string {
function GetDrivePath (line 78) | func GetDrivePath(driveId string) string {
function GetCachesDir (line 82) | func GetCachesDir() string {
function GetCacheDir (line 86) | func GetCacheDir(virtId bson.ObjectID) string {
function GetOvmfDir (line 90) | func GetOvmfDir() string {
function GetDiskPath (line 94) | func GetDiskPath(diskId bson.ObjectID) string {
function GetOvmfVarsPath (line 99) | func GetOvmfVarsPath(virtId bson.ObjectID) string {
function GetDiskTempPath (line 104) | func GetDiskTempPath() string {
function GetImageTempPath (line 109) | func GetImageTempPath() string {
function GetImdsPath (line 114) | func GetImdsPath() string {
function GetImdsConfPath (line 118) | func GetImdsConfPath(instId bson.ObjectID) string {
function GetInstRunPath (line 123) | func GetInstRunPath(instId bson.ObjectID) string {
function GetImdsSockPath (line 127) | func GetImdsSockPath(instId bson.ObjectID) string {
function GetDiskMountPath (line 131) | func GetDiskMountPath() string {
function GetInitsPath (line 135) | func GetInitsPath() string {
function GetInitPath (line 139) | func GetInitPath(instId bson.ObjectID) string {
function GetUnitName (line 144) | func GetUnitName(virtId bson.ObjectID) string {
function GetUnitPath (line 148) | func GetUnitPath(virtId bson.ObjectID) string {
function GetUnitNameDhcp4 (line 152) | func GetUnitNameDhcp4(virtId bson.ObjectID, n int) string {
function GetUnitPathDhcp4 (line 156) | func GetUnitPathDhcp4(virtId bson.ObjectID, n int) string {
function GetUnitNameDhcp6 (line 160) | func GetUnitNameDhcp6(virtId bson.ObjectID, n int) string {
function GetUnitPathDhcp6 (line 164) | func GetUnitPathDhcp6(virtId bson.ObjectID, n int) string {
function GetUnitNameNdp (line 168) | func GetUnitNameNdp(virtId bson.ObjectID, n int) string {
function GetUnitPathNdp (line 172) | func GetUnitPathNdp(virtId bson.ObjectID, n int) string {
function GetUnitNameTpm (line 177) | func GetUnitNameTpm(virtId bson.ObjectID) string {
function GetUnitPathTpm (line 181) | func GetUnitPathTpm(virtId bson.ObjectID) string {
function GetUnitNameImds (line 186) | func GetUnitNameImds(virtId bson.ObjectID) string {
function GetUnitNameDhcpc (line 190) | func GetUnitNameDhcpc(virtId bson.ObjectID) string {
function GetShareId (line 194) | func GetShareId(virtId bson.ObjectID, shareName string) string {
function GetUnitNameShare (line 202) | func GetUnitNameShare(virtId bson.ObjectID, shareId string) string {
function GetUnitNameShares (line 206) | func GetUnitNameShares(virtId bson.ObjectID) string {
function GetUnitPathImds (line 210) | func GetUnitPathImds(virtId bson.ObjectID) string {
function GetUnitPathDhcpc (line 215) | func GetUnitPathDhcpc(virtId bson.ObjectID) string {
function GetUnitPathShare (line 220) | func GetUnitPathShare(virtId bson.ObjectID, shareId string) string {
function GetUnitPathShares (line 225) | func GetUnitPathShares(virtId bson.ObjectID) string {
function GetPidPath (line 230) | func GetPidPath(virtId bson.ObjectID) string {
function GetShareSockPath (line 235) | func GetShareSockPath(virtId bson.ObjectID, shareId string) string {
function GetHugepagePath (line 240) | func GetHugepagePath(virtId bson.ObjectID) string {
function GetSockPath (line 244) | func GetSockPath(virtId bson.ObjectID) string {
function GetQmpSockPath (line 249) | func GetQmpSockPath(virtId bson.ObjectID) string {
function GetGuestPath (line 254) | func GetGuestPath(virtId bson.ObjectID) string {
function GetPidPathOld (line 260) | func GetPidPathOld(virtId bson.ObjectID) string {
function GetSockPathOld (line 266) | func GetSockPathOld(virtId bson.ObjectID) string {
function GetQmpSockPathOld (line 272) | func GetQmpSockPathOld(virtId bson.ObjectID) string {
function GetGuestPathOld (line 278) | func GetGuestPathOld(virtId bson.ObjectID) string {
function GetNamespacesPath (line 283) | func GetNamespacesPath() string {
function GetNamespacePath (line 287) | func GetNamespacePath(namespace string) string {
FILE: paths/utils.go
function existsFile (line 34) | func existsFile(pth string) (exists bool, err error) {
function FindOvmfCodePath (line 52) | func FindOvmfCodePath(secureBoot bool) (pth string, err error) {
function FindOvmfVarsPath (line 96) | func FindOvmfVarsPath(secureBoot bool) (pth string, err error) {
FILE: pci/pci.go
type Device (line 14) | type Device struct
FILE: pci/utils.go
function CheckSlot (line 16) | func CheckSlot(slot string) bool {
function GetVfio (line 20) | func GetVfio(slot string) (dev *Device, err error) {
function GetVfioAll (line 36) | func GetVfioAll() (devices []*Device, err error) {
FILE: permission/permission.go
function chown (line 15) | func chown(virt *vm.VirtualMachine, path string) (err error) {
function touchChown (line 30) | func touchChown(virt *vm.VirtualMachine, path string) (err error) {
function mkdirChown (line 46) | func mkdirChown(virt *vm.VirtualMachine, path string) (err error) {
function Restore (line 62) | func Restore(pth string) (err error) {
function Chown (line 76) | func Chown(virt *vm.VirtualMachine, pth string) (err error) {
function InitVirt (line 85) | func InitVirt(virt *vm.VirtualMachine) (err error) {
function InitDisk (line 144) | func InitDisk(virt *vm.VirtualMachine, dsk *vm.Disk) (err error) {
function InitTpm (line 158) | func InitTpm(virt *vm.VirtualMachine) (err error) {
function InitTpmPwd (line 169) | func InitTpmPwd(virt *vm.VirtualMachine) (err error) {
function InitImds (line 180) | func InitImds(virt *vm.VirtualMachine) (err error) {
function InitMount (line 191) | func InitMount(virt *vm.VirtualMachine, shareId string) (err error) {
FILE: permission/user.go
function GetUserName (line 16) | func GetUserName(vmId bson.ObjectID) string {
function UserAdd (line 20) | func UserAdd(virt *vm.VirtualMachine) (err error) {
function UserDelete (line 52) | func UserDelete(virt *vm.VirtualMachine) (err error) {
function UserGroupAdd (line 68) | func UserGroupAdd(virtId bson.ObjectID, group string) (err error) {
function UserGroupDelete (line 83) | func UserGroupDelete(virtId bson.ObjectID, group string) (err error) {
FILE: plan/constants.go
constant Start (line 8) | Start = "start"
constant Stop (line 9) | Stop = "stop"
constant Restart (line 10) | Restart = "restart"
constant Destroy (line 11) | Destroy = "destroy"
FILE: plan/data.go
type Data (line 11) | type Data struct
method Export (line 31) | func (d *Data) Export() (data eval.Data, err error) {
type Unit (line 16) | type Unit struct
type Instance (line 21) | type Instance struct
function GetEmtpyData (line 53) | func GetEmtpyData() (data eval.Data, err error) {
FILE: plan/plan.go
type Plan (line 13) | type Plan struct
method Validate (line 32) | func (p *Plan) Validate(db *database.Database) (
method UpdateStatements (line 73) | func (p *Plan) UpdateStatements(inStatements []*Statement) (err error) {
method Commit (line 106) | func (p *Plan) Commit(db *database.Database) (err error) {
method CommitFields (line 117) | func (p *Plan) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 130) | func (p *Plan) Insert(db *database.Database) (err error) {
type Completion (line 21) | type Completion struct
type Statement (line 27) | type Statement struct
FILE: plan/utils.go
function Get (line 10) | func Get(db *database.Database, plnId bson.ObjectID) (
function GetOrg (line 24) | func GetOrg(db *database.Database, orgId, plnId bson.ObjectID) (
function ExistsOrg (line 42) | func ExistsOrg(db *database.Database, orgId, plnId bson.ObjectID) (
function GetOne (line 63) | func GetOne(db *database.Database, query *bson.M) (pln *Plan, err error) {
function GetAll (line 76) | func GetAll(db *database.Database, query *bson.M) (
function GetAllPaged (line 109) | func GetAllPaged(db *database.Database, query *bson.M,
function GetAllName (line 169) | func GetAllName(db *database.Database, query *bson.M) (
function Remove (line 210) | func Remove(db *database.Database, plnId bson.ObjectID) (err error) {
function RemoveOrg (line 229) | func RemoveOrg(db *database.Database, orgId, plnId bson.ObjectID) (
function RemoveMulti (line 251) | func RemoveMulti(db *database.Database, plnIds []bson.ObjectID) (err err...
function RemoveMultiOrg (line 267) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: planner/planner.go
type Planner (line 24) | type Planner struct
method setInstanceAction (line 28) | func (p *Planner) setInstanceAction(db *database.Database,
method checkInstance (line 84) | func (p *Planner) checkInstance(db *database.Database,
method ApplyPlans (line 291) | func (p *Planner) ApplyPlans(db *database.Database) (err error) {
FILE: planner/utils.go
function buildEvalData (line 13) | func buildEvalData(unt *unit.Unit,
FILE: pod/pod.go
type Pod (line 16) | type Pod struct
method Validate (line 41) | func (p *Pod) Validate(db *database.Database) (
method Json (line 61) | func (p *Pod) Json(usrId bson.ObjectID) {
method InitUnits (line 69) | func (p *Pod) InitUnits(db *database.Database, units []*unit.UnitInput) (
method CommitFieldsUnits (line 133) | func (p *Pod) CommitFieldsUnits(db *database.Database,
method Commit (line 316) | func (p *Pod) Commit(db *database.Database) (err error) {
method CommitFields (line 327) | func (p *Pod) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 340) | func (p *Pod) Insert(db *database.Database) (err error) {
type Completion (line 26) | type Completion struct
type UnitDraft (line 32) | type UnitDraft struct
FILE: pod/utils.go
function Get (line 14) | func Get(db *database.Database, podId bson.ObjectID) (
function GetOrg (line 28) | func GetOrg(db *database.Database, orgId, pdId bson.ObjectID) (
function GetOne (line 46) | func GetOne(db *database.Database, query *bson.M) (pd *Pod, err error) {
function GetAll (line 59) | func GetAll(db *database.Database, query *bson.M) (
function GetAllPaged (line 92) | func GetAllPaged(db *database.Database, query *bson.M,
function UpdateDrafts (line 156) | func UpdateDrafts(db *database.Database, podId, usrId bson.ObjectID,
function UpdateDraftsOrg (line 179) | func UpdateDraftsOrg(db *database.Database, orgId, podId, usrId bson.Obj...
function Remove (line 203) | func Remove(db *database.Database, podId bson.ObjectID) (err error) {
function RemoveOrg (line 237) | func RemoveOrg(db *database.Database, orgId, podId bson.ObjectID) (
function RemoveMulti (line 276) | func RemoveMulti(db *database.Database, podIds []bson.ObjectID) (
function RemoveMultiOrg (line 313) | func RemoveMultiOrg(db *database.Database, orgId bson.ObjectID,
FILE: policy/constants.go
constant Optional (line 4) | Optional = "optional"
constant Required (line 5) | Required = "required"
constant Disabled (line 6) | Disabled = "disabled"
constant OperatingSystem (line 7) | OperatingSystem = "operating_system"
constant Browser (line 8) | Browser = "browser"
constant Location (line 9) | Location = "location"
constant WhitelistNetworks (line 10) | WhitelistNetworks = "whitelist_networks"
constant BlacklistNetworks (line 11) | BlacklistNetworks = "blacklist_networks"
FILE: policy/policy.go
type Rule (line 22) | type Rule struct
type Policy (line 28) | type Policy struct
method Validate (line 41) | func (p *Policy) Validate(db *database.Database) (
method ValidateUser (line 118) | func (p *Policy) ValidateUser(db *database.Database, usr *user.User,
method Commit (line 323) | func (p *Policy) Commit(db *database.Database) (err error) {
method CommitFields (line 334) | func (p *Policy) CommitFields(db *database.Database, fields set.Set) (
method Insert (line 347) | func (p *Policy) Insert(db *database.Database) (err error) {
FILE: policy/utils.go
function Get (line 10) | func Get(db *database.Database, policyId bson.ObjectID) (
function GetService (line 24) | func GetService(db *database.Database, podId bson.ObjectID) (
function GetRoles (line 62) | func GetRoles(db *database.Database, roles []string) (
function GetAll (line 106) | func GetAll(db *database.Database) (policies []*Policy, err error) {
function GetAllPaged (line 140) | func GetAllPaged(db *database.Database, query *bson.M,
function Remove (line 204) | func Remove(db *database.Database, policyId bson.ObjectID) (err error) {
function RemoveMulti (line 218) | func RemoveMulti(db *database.Database, polcyIds []bson.ObjectID) (
FILE: pool/constants.go
constant Lvm (line 4) | Lvm = "lvm"
constant Active (line 6) | Active = "active"
FILE: pool/pool.go
type Pool (line 11) | type Pool struct
method Json (line 28) | func (p *Pool) Json(nodeNames map[bson.ObjectID]string) {
method Validate (line 31) | func (p *Pool) Validate(db *database.Database) (
method Commit (line 55) | func (p *Pool) Commit(db *database.Database) (err error) {
method C
Condensed preview — 1089 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,534K chars).
[
{
"path": ".gitattributes",
"chars": 114,
"preview": "www/app/EditorThemes.ts linguist-vendored\n*.html linguist-vendored\n*.css linguist-vendored\n*.js linguist-vendored\n"
},
{
"path": ".gitignore",
"chars": 182,
"preview": ".DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nIcon?\nehthumbs.db\nThumbs.db\n*.pyc\n*.egg\n*.egg-info\nbuild_keys.json\n/pr"
},
{
"path": "CHANGES",
"chars": 10917,
"preview": "pritunl-cloud changelog\n=======================\n\n<%= version %>\n\nAdd Google Cloud DNS support\nAdd support to manual rene"
},
{
"path": "LICENSE",
"chars": 9121,
"preview": "Copyright (c) 2013-2026 Pritunl\n\n LICENSE SUMMARY\n\n* License does not expire\n* Can be used"
},
{
"path": "README.md",
"chars": 3604,
"preview": "# pritunl-cloud: declarative kvm virtualization\n\n[\n\nconst (\n\tNone = \"none\"\n\tLow "
},
{
"path": "advisory/utils.go",
"chars": 6645,
"preview": "package advisory\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"git"
},
{
"path": "agent/agent.go",
"chars": 10136,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropb"
},
{
"path": "agent/constants/constants.go",
"chars": 144,
"preview": "package constants\n\nconst (\n\tVersion = \"1.0.3248.95\"\n\tImdsConfPath = \"/etc/pritunl-imds.json\"\n\tImdsLogPath = \"/var/"
},
{
"path": "agent/imds/imds.go",
"chars": 8676,
"preview": "package imds\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"run"
},
{
"path": "agent/imds/journal.go",
"chars": 1069,
"preview": "package imds\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/agent/logging\"\n\t\"github.com/pritunl/tools/logger\"\n)\n\ntype Jour"
},
{
"path": "agent/imds/sync.go",
"chars": 1303,
"preview": "package imds\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/imds/types\"\n\t\"github.com/pritunl/pritunl-clou"
},
{
"path": "agent/imds/utils.go",
"chars": 1060,
"preview": "package imds\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/pritunl-cloud/agent"
},
{
"path": "agent/logging/file.go",
"chars": 3180,
"preview": "package logging\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"os/exec\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godro"
},
{
"path": "agent/logging/handler.go",
"chars": 182,
"preview": "package logging\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/imds/types\"\n)\n\ntype Handler interface {\n\tOpen() (err error)"
},
{
"path": "agent/logging/logging.go",
"chars": 2569,
"preview": "package logging\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritu"
},
{
"path": "agent/logging/systemd.go",
"chars": 4327,
"preview": "package logging\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"os/exec\"\n\t\"runtime/debug\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\""
},
{
"path": "agent/utils/sanitize.go",
"chars": 3058,
"preview": "package utils\n\nimport (\n\t\"strings\"\n\n\t\"github.com/pritunl/pritunl-cloud/agent/constants\"\n\t\"github.com/pritunl/tools/comma"
},
{
"path": "agent/utils/sys.go",
"chars": 472,
"preview": "package utils\n\nimport (\n\t\"io/ioutil\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/pritunl-"
},
{
"path": "aggregate/block.go",
"chars": 3770,
"preview": "package aggregate\n\nimport (\n\t\"sync\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/mongo-go-driver/"
},
{
"path": "aggregate/deployment.go",
"chars": 8047,
"preview": "package aggregate\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/da"
},
{
"path": "aggregate/disk.go",
"chars": 3455,
"preview": "package aggregate\n\nimport (\n\t\"sync\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson"
},
{
"path": "aggregate/domain.go",
"chars": 3100,
"preview": "package aggregate\n\nimport (\n\t\"sync\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson"
},
{
"path": "aggregate/instance.go",
"chars": 9772,
"preview": "package aggregate\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.co"
},
{
"path": "aggregate/pod.go",
"chars": 4375,
"preview": "package aggregate\n\nimport (\n\t\"sort\"\n\t\"sync\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driver"
},
{
"path": "aggregate/shape.go",
"chars": 3361,
"preview": "package aggregate\n\nimport (\n\t\"sync\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson"
},
{
"path": "ahandlers/alert.go",
"chars": 6538,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/audit.go",
"chars": 1006,
"preview": "package ahandlers\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/pritunl-cloud/audit\"\n\t\"github.c"
},
{
"path": "ahandlers/auth.go",
"chars": 18321,
"preview": "package ahandlers\n\nimport (\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/"
},
{
"path": "ahandlers/authority.go",
"chars": 6596,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/balancer.go",
"chars": 6388,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/block.go",
"chars": 5953,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/certificate.go",
"chars": 7117,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/check.go",
"chars": 114,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc checkGet(c *gin.Context) {\n\tc.String(200, \"ok\")\n}\n"
},
{
"path": "ahandlers/completion.go",
"chars": 5239,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritu"
},
{
"path": "ahandlers/csrf.go",
"chars": 1060,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/pritunl-cloud/authorizer\"\n\t\"github.com/prit"
},
{
"path": "ahandlers/datacenter.go",
"chars": 7122,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/devices.go",
"chars": 6878,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"githu"
},
{
"path": "ahandlers/disk.go",
"chars": 10534,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/domain.go",
"chars": 5496,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/event.go",
"chars": 3239,
"preview": "package ahandlers\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/gin-gonic/gin"
},
{
"path": "ahandlers/firewall.go",
"chars": 6157,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/handlers.go",
"chars": 10311,
"preview": "package ahandlers\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/pritunl-cloud/config\"\n\t\"github"
},
{
"path": "ahandlers/image.go",
"chars": 5038,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/instance.go",
"chars": 17779,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set"
},
{
"path": "ahandlers/license.go",
"chars": 923,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritu"
},
{
"path": "ahandlers/log.go",
"chars": 1657,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/mon"
},
{
"path": "ahandlers/node.go",
"chars": 18399,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/contai"
},
{
"path": "ahandlers/organization.go",
"chars": 4940,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/plan.go",
"chars": 4920,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/pod.go",
"chars": 18088,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/policy.go",
"chars": 6616,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/pool.go",
"chars": 5935,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/pritunl/pritunl-cloud/node\"\n\t\"github.co"
},
{
"path": "ahandlers/relations.go",
"chars": 1120,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/pritunl-cloud/database\"\n\t\"github.com/pritun"
},
{
"path": "ahandlers/secret.go",
"chars": 6200,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/session.go",
"chars": 1191,
"preview": "package ahandlers\n\nimport (\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/pritunl-cloud/database\""
},
{
"path": "ahandlers/settings.go",
"chars": 5301,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritu"
},
{
"path": "ahandlers/shape.go",
"chars": 6840,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/static.go",
"chars": 2984,
"preview": "package ahandlers\n\nimport (\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/pritunl-cloud/auth\"\n\t\"github.co"
},
{
"path": "ahandlers/storage.go",
"chars": 6449,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/subscription.go",
"chars": 1956,
"preview": "package ahandlers\n\nimport (\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/gin-gonic/gin\"\n\t\"gith"
},
{
"path": "ahandlers/theme.go",
"chars": 1000,
"preview": "package ahandlers\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritu"
},
{
"path": "ahandlers/user.go",
"chars": 7122,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set"
},
{
"path": "ahandlers/vpc.go",
"chars": 7511,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "ahandlers/zone.go",
"chars": 5348,
"preview": "package ahandlers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"gith"
},
{
"path": "alert/alert.go",
"chars": 2635,
"preview": "package alert\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"gi"
},
{
"path": "alert/constants.go",
"chars": 111,
"preview": "package alert\n\nconst (\n\tLow = 1\n\tMedium = 5\n\tHigh = 10\n)\n\nconst (\n\tInstanceOffline = \"instance_offline\"\n)\n"
},
{
"path": "alert/utils.go",
"chars": 5284,
"preview": "package alert\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"gi"
},
{
"path": "alertevent/alertevent.go",
"chars": 4069,
"preview": "package alertevent\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-"
},
{
"path": "alertevent/utils.go",
"chars": 2649,
"preview": "package alertevent\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/"
},
{
"path": "arp/arp.go",
"chars": 3668,
"preview": "package arp\n\nimport (\n\t\"encoding/json\"\n\t\"net\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dropbox/godrop"
},
{
"path": "audit/audit.go",
"chars": 948,
"preview": "package audit\n\nimport (\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\""
},
{
"path": "audit/constants.go",
"chars": 1840,
"preview": "package audit\n\nconst (\n\tAdminLogin = \"admin_login\"\n\tAdminLoginFailed = \"admin_login_failed\"\n\tA"
},
{
"path": "audit/utils.go",
"chars": 1926,
"preview": "package audit\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/mongo-go"
},
{
"path": "auth/auth.go",
"chars": 823,
"preview": "package auth\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-c"
},
{
"path": "auth/authzero.go",
"chars": 10941,
"preview": "package auth\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/e"
},
{
"path": "auth/azure.go",
"chars": 8459,
"preview": "package auth\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/"
},
{
"path": "auth/constants.go",
"chars": 57,
"preview": "package auth\n\nconst (\n\tAdmin = \"admin\"\n\tUser = \"user\"\n)\n"
},
{
"path": "auth/errortypes.go",
"chars": 115,
"preview": "package auth\n\nimport (\n\t\"github.com/dropbox/godropbox/errors\"\n)\n\ntype InvalidState struct {\n\terrors.DropboxError\n}\n"
},
{
"path": "auth/google.go",
"chars": 3938,
"preview": "package auth\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n"
},
{
"path": "auth/handler.go",
"chars": 8706,
"preview": "package auth\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha512\"\n\t\"crypto/subtle\"\n\t\"encoding/base64\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"gith"
},
{
"path": "auth/jumpcloud.go",
"chars": 4156,
"preview": "package auth\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.c"
},
{
"path": "auth/saml.go",
"chars": 2312,
"preview": "package auth\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors"
},
{
"path": "auth/state.go",
"chars": 2478,
"preview": "package auth\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/pritunl/pritunl-cloud/settings\"\n)\n\ntype StateProvider struct {\n\tId "
},
{
"path": "auth/sync.go",
"chars": 1200,
"preview": "package auth\n\nimport (\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/pritunl-cloud/databas"
},
{
"path": "auth/utils.go",
"chars": 2131,
"preview": "package auth\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/pritunl/pritunl-cloud/cookie\"\n\t\"github.com/pritunl/pr"
},
{
"path": "authority/authority.go",
"chars": 2020,
"preview": "package authority\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"githu"
},
{
"path": "authority/constants.go",
"chars": 182,
"preview": "package authority\n\nimport \"github.com/pritunl/mongo-go-driver/v2/bson\"\n\nconst (\n\tSshKey = \"ssh_key\"\n\tSshCertific"
},
{
"path": "authority/utils.go",
"chars": 7164,
"preview": "package authority\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/mongo-go-driver/v2/mongo/"
},
{
"path": "authorizer/authorizer.go",
"chars": 2266,
"preview": "package authorizer\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/pritunl/pritunl-cloud/cookie\"\n\t\"github.com/pritunl/pritunl-cloud/"
},
{
"path": "authorizer/constants.go",
"chars": 63,
"preview": "package authorizer\n\nconst (\n\tAdmin = \"admin\"\n\tUser = \"user\"\n)\n"
},
{
"path": "authorizer/utils.go",
"chars": 1833,
"preview": "package authorizer\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/pritunl/pritunl-cloud/auth\"\n\t\"github.com/pritunl/pritunl-cloud/da"
},
{
"path": "backup/backup.go",
"chars": 6512,
"preview": "package backup\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/"
},
{
"path": "balancer/balancer.go",
"chars": 7723,
"preview": "package balancer\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dropbox/god"
},
{
"path": "balancer/constants.go",
"chars": 43,
"preview": "package balancer\n\nconst (\n\tHttp = \"http\"\n)\n"
},
{
"path": "balancer/utils.go",
"chars": 3673,
"preview": "package balancer\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/mongo-go-driver/v2/mongo/o"
},
{
"path": "block/block.go",
"chars": 14756,
"preview": "package block\n\nimport (\n\t\"bytes\"\n\t\"crypto/md5\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t"
},
{
"path": "block/constants.go",
"chars": 129,
"preview": "package block\n\nconst (\n\tExternal = \"external\"\n\tHost = \"host\"\n\tNodePort = \"node_port\"\n\tIPv4 = \"ipv4\"\n\tIPv6 = "
},
{
"path": "block/errortypes.go",
"chars": 113,
"preview": "package block\n\nimport (\n\t\"github.com/dropbox/godropbox/errors\"\n)\n\ntype BlockFull struct {\n\terrors.DropboxError\n}\n"
},
{
"path": "block/ip.go",
"chars": 421,
"preview": "package block\n\nimport (\n\t\"net\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n"
},
{
"path": "block/utils.go",
"chars": 7527,
"preview": "package block\n\nimport (\n\t\"net\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"g"
},
{
"path": "bridges/bridges.go",
"chars": 2756,
"preview": "package bridges\n\nimport (\n\t\"io/ioutil\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dr"
},
{
"path": "certificate/certificate.go",
"chars": 6082,
"preview": "package certificate\n\nimport (\n\t\"crypto/md5\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com"
},
{
"path": "certificate/constants.go",
"chars": 366,
"preview": "package certificate\n\nimport \"github.com/pritunl/mongo-go-driver/v2/bson\"\n\nconst (\n\tText = \"text\"\n\tLetsEncrypt = \""
},
{
"path": "certificate/utils.go",
"chars": 5024,
"preview": "package certificate\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/mongo-go-driver/v2/mong"
},
{
"path": "cloud/cloud.go",
"chars": 421,
"preview": "package cloud\n\ntype Subnet struct {\n\tId string `bson:\"id\" json:\"id\"`\n\tVpcId string `bson:\"vpc_id\" json:\"vpc_id\"`\n"
},
{
"path": "cloud/oracle.go",
"chars": 926,
"preview": "package cloud\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/oracle\"\n)\n\nvar (\n\tlastOracleSync time.Time\n\toracleVp"
},
{
"path": "cloudinit/cloudinit.go",
"chars": 19332,
"preview": "package cloudinit\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"mime/multipart\"\n\t\"net\"\n\t\"net/textproto"
},
{
"path": "cloudinit/query.go",
"chars": 1736,
"preview": "package cloudinit\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/pritun"
},
{
"path": "cloudinit/utils.go",
"chars": 1126,
"preview": "package cloudinit\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"text/template\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"githu"
},
{
"path": "cmd/backup.go",
"chars": 482,
"preview": "package cmd\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/pritunl-cloud/ba"
},
{
"path": "cmd/dhcp.go",
"chars": 1784,
"preview": "package cmd\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pri"
},
{
"path": "cmd/imds.go",
"chars": 166,
"preview": "package cmd\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/imds/server\"\n)\n\nfunc ImdsServer() (err error) {\n\terr = server.M"
},
{
"path": "cmd/instance.go",
"chars": 1197,
"preview": "package cmd\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"gith"
},
{
"path": "cmd/log.go",
"chars": 320,
"preview": "package cmd\n\nimport (\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/pritunl/pritunl-cloud/database\"\n\t\"github.com/pritunl/pr"
},
{
"path": "cmd/mtu.go",
"chars": 176,
"preview": "package cmd\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/mtu\"\n)\n\nfunc MtuCheck() (err error) {\n\tchk := mtu.NewCheck()\n\n\t"
},
{
"path": "cmd/node.go",
"chars": 1919,
"preview": "package cmd\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl"
},
{
"path": "cmd/optimize.go",
"chars": 922,
"preview": "package cmd\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n\t\"github.com/sirupsen/logrus\"\n)\n\nfunc Optimize() (err er"
},
{
"path": "cmd/settings.go",
"chars": 4259,
"preview": "package cmd\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo"
},
{
"path": "colorize/colorize.go",
"chars": 848,
"preview": "package colorize\n\ntype Color string\n\nconst (\n\tNone = \"\"\n\tBold = \"\\033[1m\"\n\tBlack = \"\\033[0;30m\"\n\tBlackB"
},
{
"path": "completion/completion.go",
"chars": 15785,
"preview": "package completion\n\nimport (\n\t\"sort\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl"
},
{
"path": "compositor/compositor.go",
"chars": 3757,
"preview": "package compositor\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os/user\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbo"
},
{
"path": "config/config.go",
"chars": 3767,
"preview": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/g"
},
{
"path": "constants/constants.go",
"chars": 3303,
"preview": "package constants\n\nimport (\n\t\"time\"\n)\n\nconst (\n\tVersion = \"2.0.3665.99\"\n\tDatabaseVersion = 1\n\tLogPath = "
},
{
"path": "cookie/cookie.go",
"chars": 4503,
"preview": "package cookie\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dropbox/godropbox/error"
},
{
"path": "cookie/utils.go",
"chars": 1733,
"preview": "package cookie\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/gorilla/securecookie\"\n\t\"github"
},
{
"path": "crypto/crypto.go",
"chars": 7152,
"preview": "package crypto\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/rand\"\n\t\"crypto/sha512\"\n\t\"crypto/subtle\"\n\t\"encoding/base64\"\n\t\"encoding/j"
},
{
"path": "csrf/csrf.go",
"chars": 923,
"preview": "package csrf\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/database\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)"
},
{
"path": "data/disk.go",
"chars": 2554,
"preview": "package data\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/pritunl-cloud/database\"\n\t\"git"
},
{
"path": "data/image.go",
"chars": 40931,
"preview": "package data\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n"
},
{
"path": "data/resize.go",
"chars": 3939,
"preview": "package data\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/pritunl-clou"
},
{
"path": "data/sync.go",
"chars": 5882,
"preview": "package data\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/go"
},
{
"path": "data/utils.go",
"chars": 577,
"preview": "package data\n\nimport (\n\t\"crypto/md5\"\n\t\"encoding/base32\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\""
},
{
"path": "database/base.go",
"chars": 197,
"preview": "package database\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n)\n\ntype Named struct {\n\tId bson.ObjectID `bso"
},
{
"path": "database/client.go",
"chars": 857,
"preview": "package database\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/mongo\"\n\t\"g"
},
{
"path": "database/collection.go",
"chars": 7228,
"preview": "package database\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/prit"
},
{
"path": "database/database.go",
"chars": 23036,
"preview": "package database\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driv"
},
{
"path": "database/errors.go",
"chars": 493,
"preview": "package database\n\nimport (\n\t\"github.com/dropbox/godropbox/errors\"\n)\n\ntype ConnectionError struct {\n\terrors.DropboxError\n"
},
{
"path": "database/index.go",
"chars": 4012,
"preview": "package database\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"g"
},
{
"path": "database/utils.go",
"chars": 2944,
"preview": "package database\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-drive"
},
{
"path": "datacenter/constants.go",
"chars": 141,
"preview": "package datacenter\n\nconst (\n\tDefault = \"default\"\n\tVxlanVlan = \"vxlan_vlan\"\n\tWgVxlanVlan = \"wg_vxlan_vlan\"\n\n\tWg4 = "
},
{
"path": "datacenter/datacenter.go",
"chars": 5485,
"preview": "package datacenter\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"gith"
},
{
"path": "datacenter/utils.go",
"chars": 5438,
"preview": "package datacenter\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/mongo-go-driver/v2/mongo"
},
{
"path": "defaults/defaults.go",
"chars": 16332,
"preview": "package defaults\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net\"\n\t\"slices\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github."
},
{
"path": "demo/alert.go",
"chars": 433,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/alert\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar Alerts"
},
{
"path": "demo/authority.go",
"chars": 1921,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/authority\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar Au"
},
{
"path": "demo/balancer.go",
"chars": 1341,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/balance"
},
{
"path": "demo/block.go",
"chars": 1069,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/aggregate\"\n\t\"github.com/pritunl/pritunl-cloud/block\"\n\t\"github."
},
{
"path": "demo/certificate.go",
"chars": 2701,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/certifi"
},
{
"path": "demo/datacenter.go",
"chars": 700,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/datacenter\"\n\t\"gi"
},
{
"path": "demo/demo.go",
"chars": 529,
"preview": "package demo\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/pritunl/pritunl-cloud/errortypes\"\n\t\"github.com/pritunl/p"
},
{
"path": "demo/disk.go",
"chars": 13310,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/aggregate\"\n\t\"github.com/pritunl/pritunl-cloud/disk\"\n\t"
},
{
"path": "demo/domain.go",
"chars": 3321,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/domain\""
},
{
"path": "demo/firewall.go",
"chars": 806,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/firewall\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar Fir"
},
{
"path": "demo/instance.go",
"chars": 32536,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/instance\"\n\t\"github.com/pritunl/pritunl-cloud/telemetr"
},
{
"path": "demo/log.go",
"chars": 767,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/log\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar"
},
{
"path": "demo/node.go",
"chars": 25474,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/cloud\"\n"
},
{
"path": "demo/organization.go",
"chars": 304,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/organization\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar"
},
{
"path": "demo/plan.go",
"chars": 665,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/plan\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar Plans ="
},
{
"path": "demo/pod.go",
"chars": 39280,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/aggrega"
},
{
"path": "demo/policy.go",
"chars": 778,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/policy\"\n\t\"github"
},
{
"path": "demo/pool.go",
"chars": 488,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/pool\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar Pools ="
},
{
"path": "demo/rand.go",
"chars": 1171,
"preview": "package demo\n\nimport (\n\t\"sync\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n"
},
{
"path": "demo/secret.go",
"chars": 968,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/secret\"\n\t\"github"
},
{
"path": "demo/shape.go",
"chars": 1457,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/shape\"\n\t\"github."
},
{
"path": "demo/storage.go",
"chars": 714,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/storage\"\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n)\n\nvar Stor"
},
{
"path": "demo/subscription.go",
"chars": 424,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/subscription\"\n)\n\nvar Subscription = &subscription.Sub"
},
{
"path": "demo/user.go",
"chars": 2067,
"preview": "package demo\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/audit\"\n"
},
{
"path": "demo/vpc.go",
"chars": 3290,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n\t\"github.com/pritunl/pritunl-cloud/vpc\"\n)\n\nvar Vpcs = ["
},
{
"path": "demo/zone.go",
"chars": 370,
"preview": "package demo\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/utils\"\n\t\"github.com/pritunl/pritunl-cloud/zone\"\n)\n\nvar Zones ="
},
{
"path": "deploy/deploy.go",
"chars": 1655,
"preview": "package deploy\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/pritunl-cloud/database\"\n\t\"github.com/pritunl/pritunl-cloud/state\""
},
{
"path": "deploy/deployments.go",
"chars": 28465,
"preview": "package deploy\n\nimport (\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/mongo-go"
},
{
"path": "deploy/disks.go",
"chars": 12163,
"preview": "package deploy\n\nimport (\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/dropbox/godropbox/errors\"\n\t"
},
{
"path": "deploy/imds.go",
"chars": 4040,
"preview": "package deploy\n\nimport (\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/pritunl-cloud/certificate\"\n\t"
},
{
"path": "deploy/instances.go",
"chars": 23664,
"preview": "package deploy\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/d"
},
{
"path": "deploy/ipset.go",
"chars": 772,
"preview": "package deploy\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/ipset\"\n\t\"github.com/pritunl/pritunl-cloud/state\"\n)\n\ntype Ips"
},
{
"path": "deploy/iptables.go",
"chars": 637,
"preview": "package deploy\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/iptables\"\n\t\"github.com/pritunl/pritunl-cloud/state\"\n)\n\ntype "
},
{
"path": "deploy/namespace.go",
"chars": 2556,
"preview": "package deploy\n\nimport (\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/pritunl-"
},
{
"path": "deploy/network.go",
"chars": 4447,
"preview": "package deploy\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pritunl/pritunl-cloud/block\"\n\t\"github.com/pritunl/pritunl-cloud/bridges\"\n\t"
},
{
"path": "deploy/services.go",
"chars": 10953,
"preview": "package deploy\n\nimport (\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/pritunl-cloud/datab"
},
{
"path": "deployment/constants.go",
"chars": 748,
"preview": "package deployment\n\nimport (\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n)\n\nconst (\n\tProvision = \"provision\"\n"
},
{
"path": "deployment/deployment.go",
"chars": 7938,
"preview": "package deployment\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/mongo-go"
},
{
"path": "deployment/utils.go",
"chars": 6791,
"preview": "package deployment\n\nimport (\n\t\"github.com/dropbox/godropbox/container/set\"\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\""
},
{
"path": "device/constants.go",
"chars": 204,
"preview": "package device\n\nconst (\n\tU2f = \"u2f\"\n\tWebAuthn = \"webauthn\"\n\tSecondary = \"secondary\"\n\tPhone = \"phone\"\n\tCall "
},
{
"path": "device/device.go",
"chars": 5650,
"preview": "package device\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/x509\"\n\t\"time\"\n\n\t\"github.com/dropbox/godropbox/conta"
},
{
"path": "device/facet.go",
"chars": 557,
"preview": "package device\n\nimport (\n\t\"github.com/pritunl/pritunl-cloud/settings\"\n)\n\ntype FacetVersion struct {\n\tMajor int `json:\"ma"
},
{
"path": "device/utils.go",
"chars": 3976,
"preview": "package device\n\nimport (\n\t\"time\"\n\n\t\"github.com/pritunl/mongo-go-driver/v2/bson\"\n\t\"github.com/pritunl/mongo-go-driver/v2/"
},
{
"path": "dhcpc/constants.go",
"chars": 162,
"preview": "package dhcpc\n\nimport (\n\t\"time\"\n)\n\nconst (\n\tMaxMessageSize = 1500\n\tDefaultInterval = 60 * time.Second\n\tDhcpTimeout "
},
{
"path": "dhcpc/dhcpc.go",
"chars": 8317,
"preview": "package dhcpc\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pritunl/tools/lo"
},
{
"path": "dhcpc/imds.go",
"chars": 2171,
"preview": "package dhcpc\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com"
},
{
"path": "dhcpc/lease.go",
"chars": 1232,
"preview": "package dhcpc\n\nimport (\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/insomniacslk/dhcp/dhcpv6\"\n)\n\ntype Lease struct {\n\tIface "
},
{
"path": "dhcpc/lease4.go",
"chars": 2856,
"preview": "package dhcpc\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/insomniacslk/dhcp/dhcpv4\""
},
{
"path": "dhcpc/lease6.go",
"chars": 6324,
"preview": "package dhcpc\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/insomniacslk/dhcp/dhcpv6\""
},
{
"path": "dhcpc/systemd.go",
"chars": 3988,
"preview": "package dhcpc\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/pritunl/mongo-go-driver/v"
},
{
"path": "dhcpc/utils.go",
"chars": 2899,
"preview": "package dhcpc\n\nimport (\n\t\"encoding/hex\"\n\t\"net\"\n\n\t\"github.com/dropbox/godropbox/errors\"\n\t\"github.com/insomniacslk/dhcp/dh"
}
]
// ... and 889 more files (download for full content)
About this extraction
This page contains the full source code of the pritunl/pritunl-cloud GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1089 files (7.3 MB), approximately 2.0M tokens, and a symbol index with 6772 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.