Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14723948
D19323.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D19323.diff
View Options
diff --git a/resources/sql/autopatches/20180410.almanac.01.iface.xaction.sql b/resources/sql/autopatches/20180410.almanac.01.iface.xaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20180410.almanac.01.iface.xaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_almanac.almanac_interfacetransaction (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ authorPHID VARBINARY(64) NOT NULL,
+ objectPHID VARBINARY(64) NOT NULL,
+ viewPolicy VARBINARY(64) NOT NULL,
+ editPolicy VARBINARY(64) NOT NULL,
+ commentPHID VARBINARY(64) DEFAULT NULL,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
+ oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_phid` (`phid`),
+ KEY `key_object` (`objectPHID`)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -57,12 +57,19 @@
'AlmanacDrydockPoolServiceType' => 'applications/almanac/servicetype/AlmanacDrydockPoolServiceType.php',
'AlmanacEditor' => 'applications/almanac/editor/AlmanacEditor.php',
'AlmanacInterface' => 'applications/almanac/storage/AlmanacInterface.php',
+ 'AlmanacInterfaceAddressTransaction' => 'applications/almanac/xaction/AlmanacInterfaceAddressTransaction.php',
'AlmanacInterfaceDatasource' => 'applications/almanac/typeahead/AlmanacInterfaceDatasource.php',
'AlmanacInterfaceDeleteController' => 'applications/almanac/controller/AlmanacInterfaceDeleteController.php',
+ 'AlmanacInterfaceDeviceTransaction' => 'applications/almanac/xaction/AlmanacInterfaceDeviceTransaction.php',
'AlmanacInterfaceEditController' => 'applications/almanac/controller/AlmanacInterfaceEditController.php',
+ 'AlmanacInterfaceEditor' => 'applications/almanac/editor/AlmanacInterfaceEditor.php',
+ 'AlmanacInterfaceNetworkTransaction' => 'applications/almanac/xaction/AlmanacInterfaceNetworkTransaction.php',
'AlmanacInterfacePHIDType' => 'applications/almanac/phid/AlmanacInterfacePHIDType.php',
+ 'AlmanacInterfacePortTransaction' => 'applications/almanac/xaction/AlmanacInterfacePortTransaction.php',
'AlmanacInterfaceQuery' => 'applications/almanac/query/AlmanacInterfaceQuery.php',
'AlmanacInterfaceTableView' => 'applications/almanac/view/AlmanacInterfaceTableView.php',
+ 'AlmanacInterfaceTransaction' => 'applications/almanac/storage/AlmanacInterfaceTransaction.php',
+ 'AlmanacInterfaceTransactionType' => 'applications/almanac/xaction/AlmanacInterfaceTransactionType.php',
'AlmanacKeys' => 'applications/almanac/util/AlmanacKeys.php',
'AlmanacManageClusterServicesCapability' => 'applications/almanac/capability/AlmanacManageClusterServicesCapability.php',
'AlmanacManagementRegisterWorkflow' => 'applications/almanac/management/AlmanacManagementRegisterWorkflow.php',
@@ -5243,13 +5250,21 @@
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
'PhabricatorExtendedPolicyInterface',
+ 'PhabricatorApplicationTransactionInterface',
),
+ 'AlmanacInterfaceAddressTransaction' => 'AlmanacNetworkTransactionType',
'AlmanacInterfaceDatasource' => 'PhabricatorTypeaheadDatasource',
'AlmanacInterfaceDeleteController' => 'AlmanacDeviceController',
+ 'AlmanacInterfaceDeviceTransaction' => 'AlmanacNetworkTransactionType',
'AlmanacInterfaceEditController' => 'AlmanacDeviceController',
+ 'AlmanacInterfaceEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'AlmanacInterfaceNetworkTransaction' => 'AlmanacNetworkTransactionType',
'AlmanacInterfacePHIDType' => 'PhabricatorPHIDType',
+ 'AlmanacInterfacePortTransaction' => 'AlmanacNetworkTransactionType',
'AlmanacInterfaceQuery' => 'AlmanacQuery',
'AlmanacInterfaceTableView' => 'AphrontView',
+ 'AlmanacInterfaceTransaction' => 'PhabricatorModularTransaction',
+ 'AlmanacInterfaceTransactionType' => 'AlmanacTransactionType',
'AlmanacKeys' => 'Phobject',
'AlmanacManageClusterServicesCapability' => 'PhabricatorPolicyCapability',
'AlmanacManagementRegisterWorkflow' => 'AlmanacManagementWorkflow',
diff --git a/src/applications/almanac/editor/AlmanacInterfaceEditor.php b/src/applications/almanac/editor/AlmanacInterfaceEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/editor/AlmanacInterfaceEditor.php
@@ -0,0 +1,22 @@
+<?php
+
+final class AlmanacInterfaceEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorAlmanacApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Almanac Interface');
+ }
+
+ public function getCreateObjectTitle($author, $object) {
+ return pht('%s created this interface.', $author);
+ }
+
+ public function getCreateObjectTitleForFeed($author, $object) {
+ return pht('%s created %s.', $author, $object);
+ }
+
+}
diff --git a/src/applications/almanac/storage/AlmanacInterface.php b/src/applications/almanac/storage/AlmanacInterface.php
--- a/src/applications/almanac/storage/AlmanacInterface.php
+++ b/src/applications/almanac/storage/AlmanacInterface.php
@@ -5,7 +5,8 @@
implements
PhabricatorPolicyInterface,
PhabricatorDestructibleInterface,
- PhabricatorExtendedPolicyInterface {
+ PhabricatorExtendedPolicyInterface,
+ PhabricatorApplicationTransactionInterface {
protected $devicePHID;
protected $networkPHID;
@@ -154,4 +155,26 @@
$this->delete();
}
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new AlmanacInterfaceEditor();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new AlmanacInterfaceTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+ return $timeline;
+ }
+
}
diff --git a/src/applications/almanac/storage/AlmanacInterfaceTransaction.php b/src/applications/almanac/storage/AlmanacInterfaceTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/storage/AlmanacInterfaceTransaction.php
@@ -0,0 +1,22 @@
+<?php
+
+final class AlmanacInterfaceTransaction
+ extends PhabricatorModularTransaction {
+
+ public function getApplicationName() {
+ return 'almanac';
+ }
+
+ public function getApplicationTransactionType() {
+ return AlmanacInterfacePHIDType::TYPECONST;
+ }
+
+ public function getApplicationTransactionCommentObject() {
+ return null;
+ }
+
+ public function getBaseTransactionClass() {
+ return 'AlmanacInterfaceTransactionType';
+ }
+
+}
diff --git a/src/applications/almanac/xaction/AlmanacInterfaceAddressTransaction.php b/src/applications/almanac/xaction/AlmanacInterfaceAddressTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/xaction/AlmanacInterfaceAddressTransaction.php
@@ -0,0 +1,44 @@
+<?php
+
+final class AlmanacInterfaceAddressTransaction
+ extends AlmanacNetworkTransactionType {
+
+ const TRANSACTIONTYPE = 'almanac:interface:address';
+
+ public function generateOldValue($object) {
+ return $object->getAddress();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setAddress($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the address for this interface from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getAddress(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Interfaces must have an address.'));
+ }
+
+ foreach ($xactions as $xaction) {
+
+ // NOTE: For now, we don't validate addresses. We generally expect users
+ // to provide IPv4 addresses, but it's reasonable for them to provide
+ // IPv6 addresses, and some installs currently use DNS names. This is
+ // off-label but works today.
+
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/almanac/xaction/AlmanacInterfaceDeviceTransaction.php b/src/applications/almanac/xaction/AlmanacInterfaceDeviceTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/xaction/AlmanacInterfaceDeviceTransaction.php
@@ -0,0 +1,60 @@
+<?php
+
+final class AlmanacInterfaceDeviceTransaction
+ extends AlmanacNetworkTransactionType {
+
+ const TRANSACTIONTYPE = 'almanac:interface:device';
+
+ public function generateOldValue($object) {
+ return $object->getDevicePHID();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setDevicePHID($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the device for this interface from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldHandle(),
+ $this->renderNewHandle());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getAddress(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Interfaces must have a device.'));
+ }
+
+ foreach ($xactions as $xaction) {
+ if (!$this->isNewObject()) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'The device for an interface can not be changed once it has '.
+ 'been created.'),
+ $xaction);
+ continue;
+ }
+
+ $device_phid = $xaction->getNewValue();
+ $devices = id(new AlmanacDeviceQuery())
+ ->setViewer($this->getActor())
+ ->withPHIDs(array($device_phid))
+ ->execute();
+ if (!$devices) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'You can not attach an interface to a nonexistent or restricted '.
+ 'device.'),
+ $xaction);
+ continue;
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/almanac/xaction/AlmanacInterfaceNetworkTransaction.php b/src/applications/almanac/xaction/AlmanacInterfaceNetworkTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/xaction/AlmanacInterfaceNetworkTransaction.php
@@ -0,0 +1,53 @@
+<?php
+
+final class AlmanacInterfaceNetworkTransaction
+ extends AlmanacNetworkTransactionType {
+
+ const TRANSACTIONTYPE = 'almanac:interface:network';
+
+ public function generateOldValue($object) {
+ return $object->getNetworkPHID();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setNetworkPHID($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the network for this interface from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldHandle(),
+ $this->renderNewHandle());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ $network_phid = $object->getNetworkPHID();
+ if ($this->isEmptyTextTransaction($network_phid, $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Interfaces must have a network.'));
+ }
+
+ foreach ($xactions as $xaction) {
+ $network_phid = $xaction->getNewValue();
+
+ $networks = id(new AlmanacNetworkQuery())
+ ->setViewer($this->getActor())
+ ->withPHIDs(array($network_phid))
+ ->execute();
+ if (!$networks) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'You can not put an interface on a nonexistent or restricted '.
+ 'network.'),
+ $xaction);
+ continue;
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/almanac/xaction/AlmanacInterfacePortTransaction.php b/src/applications/almanac/xaction/AlmanacInterfacePortTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/xaction/AlmanacInterfacePortTransaction.php
@@ -0,0 +1,53 @@
+<?php
+
+final class AlmanacInterfacePortTransaction
+ extends AlmanacNetworkTransactionType {
+
+ const TRANSACTIONTYPE = 'almanac:interface:port';
+
+ public function generateOldValue($object) {
+ $port = $object->getPort();
+
+ if ($port !== null) {
+ $port = (int)$port;
+ }
+
+ return $port;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setPort((int)$value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the port for this interface from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Interfaces must have a port number.'));
+ }
+
+ foreach ($xactions as $xaction) {
+ $port = $xaction->getNewValue();
+
+ $port = (int)$port;
+ if ($port < 1 || $port > 65535) {
+ $errors[] = $this->newInvalidError(
+ pht('Port numbers must be between 1 and 65535, inclusive.'),
+ $xaction);
+ continue;
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/almanac/xaction/AlmanacInterfaceTransactionType.php b/src/applications/almanac/xaction/AlmanacInterfaceTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/xaction/AlmanacInterfaceTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class AlmanacInterfaceTransactionType
+ extends AlmanacTransactionType {}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 19, 12:49 AM (4 h, 57 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7014476
Default Alt Text
D19323.diff (13 KB)
Attached To
Mode
D19323: Add skeleton code for Almanac Interfaces to have real transactions
Attached
Detach File
Event Timeline
Log In to Comment