Compare commits

...

10 commits

Author SHA1 Message Date
Rodolphe Breard
8e61214017 Fix a typo 2019-09-04 17:45:19 +02:00
Rodolphe Breard
7aa04b9893 Add a "Status" section to the README 2019-09-03 11:07:13 +02:00
Rodolphe Breard
a1635a13f7 Add a vim documentation.
The README is not a sufficient enough source of information. It is
easier for vim users to access the documentation through vim itself
using the standard vim documentation.
2015-12-06 21:07:58 +01:00
Rodolphe Breard
a5e7aa3dd5 Add support for timestamp based serial.
Some people uses the current timestamp for the DNS serial number. The
current implementation detects timestamps between September 9 2001 and
March 17 2030. Implementing it has reduced the date based serial
detection to a range between 1900 and 2999, however it should not be a
problem at all because DNS didn't existed before 1900 and, if it still
exists in 3000, there is literally almost 1000 years to fix the problem.
2015-11-16 12:17:30 +01:00
Rodolphe Breard
c296d354b2 Update the code type in the README.
The sample custom patterns were defined as `json`, which doesn't renders
nicely on GitHub. They are now defined as `js` which is much more
readable.
2015-11-15 00:06:58 +01:00
Rodolphe Breard
317389ec31 Add the support for multiple formats.
Some people does not use the common YYYYMMDDXX format and/or does not
want to use the "; serial" comment right after the serial number. This
commit allow multiple formats to be defined, hense more users can use
the plugin. A huge consequence of this is that user can also define
additional custom formats depending on their needs.
2015-11-15 00:02:46 +01:00
Rodolphe Breard
acc6dd81e1 Add a Patterns section to the README.
The documentation on how the DNS serial number have to be formated was
missing. Even if the pattern is very common, it is important to specify
it.
2015-11-14 19:32:44 +01:00
Rodolphe Breard
2f1756485c Add a Usage section in the README.
Users shouldn't have to guess neither that the plugin auto-updates the
DNS serial number nor the name of the function to call to manually
update it.
2015-11-14 19:12:03 +01:00
Rodolphe Breard
a4c03b38a5 Add the possibility to turn off the automatic serial update.
Some users may want to explicitly update the DNS serial number. Instead
of forcing them to update on each write, a new configuration option is
used so they can chose turn it off.
2015-11-14 19:05:12 +01:00
Rodolphe Breard
d54d2f0991 Add a badge with the license.
Using such a badge allows the user to quickly identify the license.
2015-11-09 11:28:56 +01:00
5 changed files with 343 additions and 23 deletions

104
README.md
View file

@ -1,6 +1,8 @@
vim-dnsserial vim-dnsserial
============= =============
[![Apache License 2.0](https://img.shields.io/github/license/breard-r/vim-dnsserial.svg "Apache License 2.0")](https://www.apache.org/licenses/LICENSE-2.0.html)
Another DNS-zone serial number updater. Another DNS-zone serial number updater.
@ -15,3 +17,105 @@ I know this not the first vim plugin available to update a DNS-zone serial numbe
* it lacks functionalities. * it lacks functionalities.
It chose not to fork the original plugin but to write a new one from scratch mainly for legal purposes, but also because I did not found the code as simple as I expected. It chose not to fork the original plugin but to write a new one from scratch mainly for legal purposes, but also because I did not found the code as simple as I expected.
Status
------
This project is passively maintained. If there is no recent commits it is because:
- I did not encountered a bug and nobody reported any.
- I am happy with the functionalities and nobody asked for new ones.
- It works on both vim and neovim.
If you need anything, please open an issue.
Usage
-----
By default, each time you save a `bindzone` file, the script will look for the DNS serial number and update it. You can also update it without saving the file by invoking the `:DNSSerialUpdate` function.
Patterns
--------
In order to be detected, the DNS serial number must match one the following pattern:
* `YYYYMMDDXX ; serial`
- `YYYY` is the year (4 digits, must start by either `19` or `2`);
- `MM` is the month (2 digits);
- `DD` is the day (2 digits);
- `XX` is any non-negative number (1 or more digits);
- the word `serial` is not case-sensitive;
- there can be any number of blanks on each sides of the semicolon.
* `SSSSSSSSSS ; serial`
- `SSSSSSSSSS` is the UNIX timestamp (10 digits, must start by `1`);
- the word `serial` is not case-sensitive;
- there can be any number of blanks on each sides of the semicolon.
* `XX ; serial`
- `XX` is any non-negative number (1 or more digits);
- the word `serial` is not case-sensitive;
- there can be any number of blanks on each sides of the semicolon.
According to those patterns, only dates between 1900 and 2999 will be detected; however this should not be a problem at all. Most importantly, only timestamps between September 9 2001 and March 17 2030 will be detected.
Configuration
-------------
You can set several configuration variables in your vimrc:
* `g:dnsserial_auto_update`: Defines whether or not the serial is updated when the zone file is saved (default is 1, set it to 0 to disable).
* `g:dnsserial_custom_patterns`: List of customs patterns that will be added to the default ones. Order matters, the first matching patters will be used. Customs patterns will be tested before the default ones.
* `g:dnsserial_patterns`: List of default patterns. It is not advised to change it.
Custom patterns
---------------
A pattern is defined by a dictionary with two keys: `regex` and `matching`.
**regex**
Contains the regular expression that will be used to search the document for the serial number. All the components of the serial number must be captured with parenthesis.
**matching**
This is a list of every components of the serial number. Each component is defined by a dictionary. The `type` key must be present and contain one of the allowed types. Depending on the type, several additional keys might be defined. Authorized types and their options are:
* `raw`: Raw string.
* `integer`: An integer that will be incremented.
- `offset` (int): set the offset by which the integer is incremented. Default is 1.
- `padding` (int): Force the integer to be 0-padded on the associated number of digits.
- `date_reset` (bool): If set to 1 and a the serial contains a `date`, the integer will be reseted to 0 if the date is updated. Default is 0.
* `date`: A formated date that will be updated to the current one.
- `fmt` (string, mandatory) : the date format according to the `strftime()` specifications. See `:help strftime` for more details.
**examples**
A simple pattern matching a serial defined as an integer and followed by a comment starting by the word `serial` is:
```js
{
'regex': '\(\d\+\)\s*;\s*\cserial',
'matching': [
{'type': 'integer'}
]
}
```
The same example, but having the serial number starting by the current date (YYYYMMDD) and the integer padded on two digits:
```js
{
'regex': '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial',
'matching': [
{'type': 'date', 'fmt': '%Y%m%d'},
{'type': 'integer', 'padding': 2, 'date_reset': 1}
]
}
```

View file

@ -12,28 +12,59 @@
" See the License for the specific language governing permissions and " See the License for the specific language governing permissions and
" limitations under the License. " limitations under the License.
function! s:IncrementSerial(old_date, old_nb)
let curr_date = strftime("%Y%m%d") function! s:HasDateChanged(pattern, old_matchlist)
if a:old_date ==? curr_date let i = 0
let curr_nb = a:old_nb + 1 for matching in a:pattern.matching
if curr_nb < 10 if matching.type ==? 'date'
let curr_nb = "0".curr_nb let old_date = a:old_matchlist[i]
let new_date = strftime(matching.fmt)
if old_date !=? new_date
return 1
endif
endif endif
else let i += 1
let curr_nb = "01" endfor
return 0
endfunction
function! s:GetNewValue(matching, old_value, date_changed)
if a:matching.type ==? 'date'
return strftime(a:matching.fmt)
elseif a:matching.type ==? 'integer'
let nb = a:old_value + get(a:matching, 'offset', 1)
if a:date_changed && get(a:matching, 'date_reset', 0)
let nb = 0
endif
return printf('%0' . get(a:matching, 'padding', 1) . 'd', nb)
endif endif
return curr_date.curr_nb return a:old_value
endfunction
function! s:GetNewSerial(pattern, old_matchlist)
let date_changed = s:HasDateChanged(a:pattern, a:old_matchlist)
let new_serial = []
let i = 0
for matching in a:pattern.matching
let new_value = s:GetNewValue(matching, a:old_matchlist[i], date_changed)
call add(new_serial, new_value)
let i += 1
endfor
return join(new_serial, '')
endfunction endfunction
function! dnsserial#DNSSerialUpdate() function! dnsserial#DNSSerialUpdate()
let pattern = '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial' let patterns = g:dnsserial_custom_patterns + g:dnsserial_patterns
if search(pattern) == 0 for pattern in patterns
echom "No serial found." if search(pattern.regex) != 0
return 0 let offset = len(pattern.matching)
endif let old_matchlist = matchlist(getline('.'), pattern.regex)[1:offset]
let old_pattern = matchlist(getline('.'), pattern) let old_serial = join(old_matchlist, '')
let old_serial = old_pattern[1].old_pattern[2] let new_serial = s:GetNewSerial(pattern, old_matchlist)
let new_serial = s:IncrementSerial(old_pattern[1], old_pattern[2]) execute "s/" . old_serial . "/" . new_serial . "/"
execute "s/".old_serial."/".new_serial."/" echom "Serial updated to " . new_serial . "."
echom "Serial updated to ".new_serial."." return 0
endif
endfor
echom "No serial found."
endfunction endfunction

147
doc/dnsserial.txt Normal file
View file

@ -0,0 +1,147 @@
*dnsserial.txt* another DNS-zone serial number updater
____ _ _ ____ _ _ ~
| _ \| \ | / ___| ___ ___ _ __(_) __ _| |~
| | | | \| \___ \/ __|/ _ \ '__| |/ _` | |~
| |_| | |\ |___) \__ \ __/ | | | (_| | |~
|____/|_| \_|____/|___/\___|_| |_|\__,_|_|~
Another DNS-zone serial number updater.
==============================================================================
CONTENTS *DNSserialContents*
1. Introduction ......... |DNSserial|
2. Usage ................ |DNSserialUsage|
3. Patterns ............. |DNSserialPatterns|
4. Configuration ........ |DNSserialConfiguration|
5. Custom patterns ...... |DNSserialCustomPatterns|
5.1 regex ........... |DNSserialCustomPatterns-regex|
5.2 matching ........ |DNSserialCustomPatterns-matching|
5.3 examples ........ |DNSserialCustomPatterns-examples|
6. License .............. |DNSserialLicense|
==============================================================================
Section 1: Introduction *DNSserial*
I know this not the first vim plugin available to update a DNS-zone serial
number. Here is a few reasons why I chose not to use the canonical one:
- there is no license and therefore it is not free;
- it is unmaintained;
- it is bugged;
- it lacks functionalities.
It chose not to fork the original plugin but to write a new one from scratch
mainly for legal purposes, but also because I did not found the code as simple
as I expected.
==============================================================================
Section 2: Usage *DNSserialUsage*
By default, each time you save a bindzone file, the script will look for the
DNS serial number and update it. You can also update it without saving the
file by invoking the :DNSSerialUpdate function.
==============================================================================
Section 3: Patterns *DNSserialPatterns*
In order to be detected, the DNS serial number must match one the following
pattern:
- YYYYMMDDXX ; serial
* YYYY is the year (4 digits, must start by either 19 or 2);
* MM is the month (2 digits);
* DD is the day (2 digits);
* XX is any non-negative number (1 or more digits);
* the word serial is not case-sensitive;
* there can be any number of blanks on each sides of the semicolon.
- SSSSSSSSSS ; serial
* SSSSSSSSSS is the UNIX tiemstamp (10 digits, must start by 1);
* the word serial is not case-sensitive;
* there can be any number of blanks on each sides of the semicolon.
- XX ; serial
* XX is any non-negative number (1 or more digits);
* the word serial is not case-sensitive;
* there can be any number of blanks on each sides of the semicolon.
According to those patterns, only dates between 1900 and 2999 will be
detected; however this should not be a problem at all. Most importantly, only
timestamps between September 9 2001 and March 17 2030 will be detected.
==============================================================================
Section 4: Configuration *DNSserialConfiguration*
You can set several configuration variables in your vimrc:
- g:dnsserial_auto_update: Defines whether or not the serial is updated when
the zone file is saved (default is 1, set it to 0 to disable).
- g:dnsserial_custom_patterns: List of customs patterns that will be added to
the default ones. Order matters, the first matching patters will be used.
Customs patterns will be tested before the default ones.
- g:dnsserial_patterns: List of default patterns. It is not advised to change
it.
==============================================================================
Section 5: Custom patterns *DNSserialCustomPatterns*
A pattern is defined by a dictionary with two keys: regex and matching.
------------------------------------------------------------------------------
Section 5.1: regex *DNSserialCustomPatterns-regex*
Contains the regular expression that will be used to search the document for
the serial number. All the components of the serial number must be captured
with parenthesis.
------------------------------------------------------------------------------
Section 5.1: matching *DNSserialCustomPatterns-matching*
This is a list of every components of the serial number. Each component is
defined by a dictionary. The type key must be present and contain one of the
allowed types. Depending on the type, several additional keys might be
defined. Authorized types and their options are:
- raw: Raw string.
- integer: An integer that will be incremented.
- offset (int): set the offset by which the integer is incremented. Default
is 1.
- padding (int): Force the integer to be 0-padded on the associated number of
digits.
- date_reset (bool): If set to 1 and a the serial contains a date, the
integer will be reseted to 0 if the date is updated. Default is 0.
- date: A formated date that will be updated to the current one.
- fmt (string, mandatory) : the date format according to the strftime()
specifications. See :help strftime for more details.
------------------------------------------------------------------------------
Section 5.1: examples *DNSserialCustomPatterns-examples*
A simple pattern matching a serial defined as an integer and followed by a
comment starting by the word serial is:
{
'regex': '\(\d\+\)\s*;\s*\cserial',
'matching': [
{'type': 'integer'}
]
}
The same example, but having the serial number starting by the current date
(YYYYMMDD) and the integer padded on two digits:
{
'regex': '\(\d\{8}\)\(\d\+\)\s*;\s*\cserial',
'matching': [
{'type': 'date', 'fmt': '%Y%m%d'},
{'type': 'integer', 'padding': 2, 'date_reset': 1}
]
}
==============================================================================
Section 6: License *DNSserialLicense*
DNSserial is Copyright 2015 Rodolphe Breard and is licensed under the Apache
License, Version 2.0.

View file

@ -13,7 +13,13 @@
" limitations under the License. " limitations under the License.
augroup dnsserial if !exists('g:dnsserial_auto_update')
autocmd! let g:dnsserial_auto_update = 1
autocmd BufWritePre <buffer> DNSSerialUpdate endif
augroup END
if g:dnsserial_auto_update
augroup dnsserial
autocmd!
autocmd BufWritePre <buffer> DNSSerialUpdate
augroup END
endif

View file

@ -12,4 +12,36 @@
" See the License for the specific language governing permissions and " See the License for the specific language governing permissions and
" limitations under the License. " limitations under the License.
if !exists('g:dnsserial_custom_patterns')
let g:dnsserial_custom_patterns = []
endif
if !exists('g:dnsserial_patterns')
let g:dnsserial_patterns = [
\{
\'regex': '\(19\d\{2}\|20\d\{2}\)\([01]\d\)\([0-3]\d\)\(\d\+\)\s*;\s*\cserial',
\'matching': [
\{'type': 'date', 'fmt': '%Y'},
\{'type': 'date', 'fmt': '%m'},
\{'type': 'date', 'fmt': '%d'},
\{'type': 'integer', 'padding': 2, 'date_reset': 1}
\]
\},
\{
\'regex': '\(1\d\{9}\)\s*;\s*\cserial',
\'matching': [
\{'type': 'date', 'fmt': '%s'},
\]
\},
\{
\'regex': '\(\d\+\)\s*;\s*\cserial',
\'matching': [
\{'type': 'integer'}
\]
\},
\]
endif
command! DNSSerialUpdate call dnsserial#DNSSerialUpdate() command! DNSSerialUpdate call dnsserial#DNSSerialUpdate()